diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/CREDITS linux-2.4.29-pre3/CREDITS
--- linux-2.4.28/CREDITS	2004-12-22 16:17:15.463611864 +0000
+++ linux-2.4.29-pre3/CREDITS	2004-12-22 16:07:14.297003080 +0000
@@ -1447,8 +1447,9 @@ S: D 67659 Kaiserslautern
 S: Germany
 
 N: Mike Jagdis
-E: jaggy@purplet.demon.co.uk
-E: Mike.Jagdis@purplet.demon.co.uk
+E: mjagdis@eris-associates.co.uk
+E: jaggy@jaggycraft.co.uk
+E: Mike.Jagdis@eris-associates.co.uk
 D: iBCS personalities, socket and X interfaces, x.out loader, syscalls...
 D: Purple Distribution maintainer
 D: UK FidoNet support
@@ -1457,7 +1458,7 @@ D: Kernel and device driver hacking
 S: 280 Silverdale Road
 S: Earley
 S: Reading
-S: RG6 2NU
+S: RG6 7NU
 S: United Kingdom
 
 N: Jakub Jelinek
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/Documentation/Configure.help linux-2.4.29-pre3/Documentation/Configure.help
--- linux-2.4.28/Documentation/Configure.help	2004-12-22 16:17:15.526602288 +0000
+++ linux-2.4.29-pre3/Documentation/Configure.help	2004-12-22 16:07:39.826122064 +0000
@@ -617,6 +617,8 @@ CONFIG_BLK_STATS
 
   This is required for the full functionality of sar(8) and interesting
   if you want to do performance tuning, by tweaking the elevator, e.g.
+  On the other hand, it will cause random and mysterious failures for
+  fdisk, mount and other programs reading /proc/partitions.
 
   If unsure, say N.
 
@@ -1317,21 +1319,6 @@ CONFIG_BLK_DEV_PIIX
 
   Please read the comments at the top of <file:drivers/ide/pci/piix.c>.
 
-  If you say Y here, you should also say Y to "PIIXn Tuning support",
-  below.
-
-  If unsure, say N.
-
-PIIXn Tuning support
-CONFIG_PIIX_TUNING
-  This driver extension adds DMA mode setting and tuning for all PIIX
-  IDE controllers by Intel. Since the BIOS can sometimes improperly
-  set up the device/adapter combination and speed limits, it has
-  become a necessity to back/forward speed devices as needed.
-
-  Case 430HX/440FX PIIX3 need speed limits to reduce UDMA to DMA mode
-  2 if the BIOS can not perform this task at initialization.
-
   If unsure, say N.
 
 Promise PDC202{46|62|65|67} support
@@ -2557,9 +2544,9 @@ CONFIG_PCMCIA_FDOMAIN
 
 # Choice: mipstype
 CPU type
-CONFIG_CPU_R3000
+CONFIG_CPU_MIPS32
   Please make sure to pick the right CPU type. Linux/MIPS is not
-  designed to be generic, i.e. Kernels compiled for R3000 CPUs will
+  designed to be generic, i.e. kernels compiled for R3000 CPUs will
   *not* work on R4000 machines and vice versa.  However, since most
   of the supported machines have an R4000 (or similar) CPU, R4x00
   might be a safe bet.  If the resulting kernel does not work,
@@ -2683,6 +2670,19 @@ CONFIG_CPU_HAS_WB
   machines which require flushing of write buffers in software.  Saying
   Y is the safe option; N may result in kernel malfunction and crashes.
 
+Use 64-bit ELF format for building
+CONFIG_BUILD_ELF64
+  A 64-bit kernel is usually built using the 64-bit ELF binary object
+  format as it's one that allows arbitrary 64-bit constructs.  For
+  kernels that are loaded within the KSEG compatibility segments the
+  32-bit ELF format can optionally be used resulting in a somewhat
+  smaller binary, but this option is not explicitly supported by the
+  toolchain and since binutils 2.14 it does not even work at all.
+
+  Say Y to use the 64-bit format or N to use the 32-bit one.
+
+  If unsure say Y.
+
 Support for large 64-bit configurations
 CONFIG_MIPS_INSANE_LARGE
   MIPS R10000 does support a 44 bit / 16TB address space as opposed to
@@ -5214,10 +5214,17 @@ CONFIG_FB_CT65550
   This is the frame buffer device driver for the Chips & Technologies
   65550 graphics chip in PowerBooks.
 
-TGA frame buffer support
+TGA/SFB+ frame buffer support
 CONFIG_FB_TGA
-  This is the frame buffer device driver for generic TGA graphic
-  cards. Say Y if you have one of those.
+  This is the frame buffer device driver for generic TGA and SFB+
+  graphic cards.  These include DEC ZLXp-E1, E2 and E3 PCI cards,
+  also known as PBXGA-A, B and C, and DEC ZLX-E2 and E3 TURBOchannel
+  cards, also known as PMAGD-B and C.  The DEC ZLX-E1 or PMAGD-A card
+  is currently unsupported.  Due to hardware limitations ZLX-E2 and
+  E3 cards are only supported for DECstation 5000/1xx and Personal
+  DECstation 5000/xx systems.
+
+  Say Y if you have one of those.
 
 VESA VGA graphics console
 CONFIG_FB_VESA
@@ -7739,7 +7746,7 @@ CONFIG_FUSION_CTL
   of MPT adapters via system ioctl calls.  Use of ioctl calls to
   the MPT driver requires that you create and use a misc device
   node ala:
-    mknod /dev/mptctl c 10 240
+    mknod /dev/mptctl c 10 220
 
   One use of this ioctl interface is to perform an upgrade (reflash)
   of the MPT adapter firmware.  Refer to readme file(s) distributed
@@ -9325,6 +9332,11 @@ CONFIG_SCSI_SATA
 
   If unsure, say N.
 
+CONFIG_SCSI_SATA_AHCI
+  This option enables support for AHCI Serial ATA.
+
+  If unsure, say N.
+
 CONFIG_SCSI_SATA_SVW
   This option enables support for Broadcom/Serverworks/Apple K2
   SATA support.
@@ -12204,65 +12216,16 @@ CONFIG_DL2K
 
 EtherExpress Pro/100 support (e100, Alternate Intel driver)
 CONFIG_E100
-  This driver supports Intel(R) PRO/100 family of adapters, which
-  includes:
-
-     Controller  Adapter Name                       Board IDs
-     ----------  ------------                       ---------
-
-     82558       PRO/100+ PCI Adapter               668081-xxx,
-                                                    689661-xxx
-     82558       PRO/100+ Management Adapter        691334-xxx,
-                                                    701738-xxx,
-                                                    721383-xxx
-     82558       PRO/100+ Dual Port Server Adapter  714303-xxx,
-                                                    711269-xxx,
-                                                    A28276-xxx
-     82558       PRO/100+ PCI Server Adapter        710550-xxx
-     82550       PRO/100 S Server Adapter           752438-xxx
-     82559                                          A56831-xxx,
-                                                    A10563-xxx,
-                                                    A12171-xxx,
-                                                    A12321-xxx,
-                                                    A12320-xxx,
-                                                    A12170-xxx
-                                                    748568-xxx
-                                                    748565-xxx
-     82550       PRO/100 S Desktop Adapter          751767-xxx
-     82559                                          748592-xxx,
-                                                    A12167-xxx,
-                                                    A12318-xxx,
-                                                    A12317-xxx,
-                                                    A12165-xxx,
-                                                    748569-xxx
-     82559       PRO/100+ Server Adapter            729757-xxx
-     82559       PRO/100 S Management Adapter       748566-xxx,
-                                                    748564-xxx
-     82550       PRO/100 S Dual Port Server Adapter A56831-xxx
-     82551       PRO/100 M Desktop Adapter          A80897-xxx
-                 PRO/100 S Advanced Management Adapter
-                                                    747842-xxx,
-                                                    745171-xxx
-     CNR         PRO/100 VE Desktop Adapter         A10386-xxx,
-                                                    A10725-xxx,
-                                                    A23801-xxx,
-                                                    A19716-xxx
-                 PRO/100 VM Desktop Adapter         A14323-xxx,
-                                                    A19725-xxx,
-                                                    A23801-xxx,
-                                                    A22220-xxx,
-                                                    A23796-xxx
-
-
+  This driver supports Intel(R) PRO/100 family of adapters.
   To verify that your adapter is supported, find the board ID number
   on the adapter. Look for a label that has a barcode and a number
-  in the format 123456-001 (six digits hyphen three digits). Match
-  this to the list of numbers above.
+  in the format 123456-001 (six digits hyphen three digits).
 
-  For more information on how to identify your adapter, go to the
-  Adapter & Driver ID Guide at:
+  Use the above information and the Adapter & Driver ID Guide at:
+
+  http://support.intel.com/support/network/adapter/pro100/21397.htm
 
-    http://support.intel.com/support/network/adapter/pro100/21397.htm
+  to identify the adapter.
 
   For the latest Intel PRO/100 network driver for Linux, see:
 
@@ -12280,28 +12243,7 @@ CONFIG_E100
 Intel(R) PRO/1000 Gigabit Ethernet support
 CONFIG_E1000
   This driver supports Intel(R) PRO/1000 gigabit ethernet family of
-  adapters, which includes:
-
-     Controller  Adapter Name                         Board IDs
-     ----------  ------------                         ---------
-     82542       PRO/1000 Gigabit Server Adapter      700262-xxx,
-                                                      717037-xxx
-     82543       PRO/1000 F Server Adapter            738640-xxx,
-                                                      A38888-xxx
-     82543       PRO/1000 T Server Adapter            A19845-xxx,
-                                                      A33948-xxx
-     82544       PRO/1000 XT Server Adapter           A51580-xxx
-     82544       PRO/1000 XF Server Adapter           A50484-xxx
-     82544       PRO/1000 T Desktop Adapter           A62947-xxx
-     82540       PRO/1000 MT Desktop Adapter          A78408-xxx
-     82541       PRO/1000 MT Desktop Adapter          C91016-xxx
-     82545       PRO/1000 MT Server Adapter           A92165-xxx
-     82546       PRO/1000 MT Dual Port Server Adapter A92111-xxx
-     82545       PRO/1000 MF Server Adapter           A91622-xxx
-     82545       PRO/1000 MF Server Adapter(LX)       A91624-xxx
-     82546       PRO/1000 MF Dual Port Server Adapter A91620-xxx 
-
-  For more information on how to identify your adapter, go to the
+  adapters. For more information on how to identify your adapter, go to the
   Adapter & Driver ID Guide at:
 
    <http://support.intel.com/support/network/adapter/pro100/21397.htm>
@@ -13588,10 +13530,11 @@ CONFIG_FDDI
   then also Y to the driver for your FDDI card, below). Most people
   will say N.
 
-Digital DEFEA and DEFPA adapter support
+Digital DEFTA/DEFEA/DEFPA adapter support
 CONFIG_DEFXX
-  This is support for the DIGITAL series of EISA (DEFEA) and PCI
-  (DEFPA) controllers which can connect you to a local FDDI network.
+  This is support for the DIGITAL series of TURBOchannel (DEFTA), EISA
+  (DEFEA) and PCI (DEFPA) controllers which can connect you to a local
+  FDDI network.
 
   If you want to compile the driver as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/Documentation/DocBook/libata.tmpl linux-2.4.29-pre3/Documentation/DocBook/libata.tmpl
--- linux-2.4.28/Documentation/DocBook/libata.tmpl	2004-08-07 23:26:04.000000000 +0000
+++ linux-2.4.29-pre3/Documentation/DocBook/libata.tmpl	2004-12-22 16:06:24.614555960 +0000
@@ -61,6 +61,196 @@
   </para>
   </chapter>
 
+  <chapter id="libataDriverApi">
+     <title>libata Driver API</title>
+     <sect1>
+        <title>struct ata_port_operations</title>
+
+	<programlisting>
+void (*port_disable) (struct ata_port *);
+	</programlisting>
+
+	<para>
+	Called from ata_bus_probe() and ata_bus_reset() error paths,
+	as well as when unregistering from the SCSI module (rmmod, hot
+	unplug).
+	</para>
+
+	<programlisting>
+void (*dev_config) (struct ata_port *, struct ata_device *);
+	</programlisting>
+
+	<para>
+	Called after IDENTIFY [PACKET] DEVICE is issued to each device
+	found.  Typically used to apply device-specific fixups prior to
+	issue of SET FEATURES - XFER MODE, and prior to operation.
+	</para>
+
+	<programlisting>
+void (*set_piomode) (struct ata_port *, struct ata_device *);
+void (*set_dmamode) (struct ata_port *, struct ata_device *);
+void (*post_set_mode) (struct ata_port *ap);
+	</programlisting>
+
+	<para>
+	Hooks called prior to the issue of SET FEATURES - XFER MODE
+	command.  dev->pio_mode is guaranteed to be valid when
+	->set_piomode() is called, and dev->dma_mode is guaranteed to be
+	valid when ->set_dmamode() is called.  ->post_set_mode() is
+	called unconditionally, after the SET FEATURES - XFER MODE
+	command completes successfully.
+	</para>
+
+	<para>
+	->set_piomode() is always called (if present), but
+	->set_dma_mode() is only called if DMA is possible.
+	</para>
+
+	<programlisting>
+void (*tf_load) (struct ata_port *ap, struct ata_taskfile *tf);
+void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
+	</programlisting>
+
+	<para>
+	->tf_load() is called to load the given taskfile into hardware
+	registers / DMA buffers.  ->tf_read() is called to read the
+	hardware registers / DMA buffers, to obtain the current set of
+	taskfile register values.
+	</para>
+
+	<programlisting>
+void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
+	</programlisting>
+
+	<para>
+	causes an ATA command, previously loaded with
+	->tf_load(), to be initiated in hardware.
+	</para>
+
+	<programlisting>
+u8   (*check_status)(struct ata_port *ap);
+void (*dev_select)(struct ata_port *ap, unsigned int device);
+	</programlisting>
+
+	<para>
+	Reads the Status ATA shadow register from hardware.  On some
+	hardware, this has the side effect of clearing the interrupt
+	condition.
+	</para>
+
+	<programlisting>
+void (*dev_select)(struct ata_port *ap, unsigned int device);
+	</programlisting>
+
+	<para>
+	Issues the low-level hardware command(s) that causes one of N
+	hardware devices to be considered 'selected' (active and
+	available for use) on the ATA bus.
+	</para>
+
+	<programlisting>
+void (*phy_reset) (struct ata_port *ap);
+	</programlisting>
+
+	<para>
+	The very first step in the probe phase.  Actions vary depending
+	on the bus type, typically.  After waking up the device and probing
+	for device presence (PATA and SATA), typically a soft reset
+	(SRST) will be performed.  Drivers typically use the helper
+	functions ata_bus_reset() or sata_phy_reset() for this hook.
+	</para>
+
+	<programlisting>
+void (*bmdma_setup) (struct ata_queued_cmd *qc);
+void (*bmdma_start) (struct ata_queued_cmd *qc);
+	</programlisting>
+
+	<para>
+	When setting up an IDE BMDMA transaction, these hooks arm
+	(->bmdma_setup) and fire (->bmdma_start) the hardware's DMA
+	engine.
+	</para>
+
+	<programlisting>
+void (*qc_prep) (struct ata_queued_cmd *qc);
+int (*qc_issue) (struct ata_queued_cmd *qc);
+	</programlisting>
+
+	<para>
+	Higher-level hooks, these two hooks can potentially supercede
+	several of the above taskfile/DMA engine hooks.  ->qc_prep is
+	called after the buffers have been DMA-mapped, and is typically
+	used to populate the hardware's DMA scatter-gather table.
+	Most drivers use the standard ata_qc_prep() helper function, but
+	more advanced drivers roll their own.
+	</para>
+	<para>
+	->qc_issue is used to make a command active, once the hardware
+	and S/G tables have been prepared.  IDE BMDMA drivers use the
+	helper function ata_qc_issue_prot() for taskfile protocol-based
+	dispatch.  More advanced drivers roll their own ->qc_issue
+	implementation, using this as the "issue new ATA command to
+	hardware" hook.
+	</para>
+
+	<programlisting>
+void (*eng_timeout) (struct ata_port *ap);
+	</programlisting>
+
+	<para>
+	This is a high level error handling function, called from the
+	error handling thread, when a command times out.
+	</para>
+
+	<programlisting>
+irqreturn_t (*irq_handler)(int, void *, struct pt_regs *);
+void (*irq_clear) (struct ata_port *);
+	</programlisting>
+
+	<para>
+	->irq_handler is the interrupt handling routine registered with
+	the system, by libata.  ->irq_clear is called during probe just
+	before the interrupt handler is registered, to be sure hardware
+	is quiet.
+	</para>
+
+	<programlisting>
+u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg);
+void (*scr_write) (struct ata_port *ap, unsigned int sc_reg,
+                   u32 val);
+	</programlisting>
+
+	<para>
+	Read and write standard SATA phy registers.  Currently only used
+	if ->phy_reset hook called the sata_phy_reset() helper function.
+	</para>
+
+	<programlisting>
+int (*port_start) (struct ata_port *ap);
+void (*port_stop) (struct ata_port *ap);
+void (*host_stop) (struct ata_host_set *host_set);
+	</programlisting>
+
+	<para>
+	->port_start() is called just after the data structures for each
+	port are initialized.  Typically this is used to alloc per-port
+	DMA buffers / tables / rings, enable DMA engines, and similar
+	tasks.  
+	</para>
+	<para>
+	->host_stop() is called when the rmmod or hot unplug process
+	begins.  The hook must stop all hardware interrupts, DMA
+	engines, etc.
+	</para>
+	<para>
+	->port_stop() is called after ->host_stop().  It's sole function
+	is to release DMA/memory resources, now that they are no longer
+	actively being used.
+	</para>
+
+     </sect1>
+  </chapter>
+
   <chapter id="libataExt">
      <title>libata Library</title>
 !Edrivers/scsi/libata-core.c
@@ -78,7 +268,7 @@
   </chapter>
 
   <chapter id="SILInt">
-     <title>ata_sil Internals</title>
+     <title>sata_sil Internals</title>
 !Idrivers/scsi/sata_sil.c
   </chapter>
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/Documentation/filesystems/proc.txt linux-2.4.29-pre3/Documentation/filesystems/proc.txt
--- linux-2.4.28/Documentation/filesystems/proc.txt	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.29-pre3/Documentation/filesystems/proc.txt	2004-12-22 16:06:06.572298800 +0000
@@ -936,239 +936,7 @@ program to load modules on demand.
 
 2.4 /proc/sys/vm - The virtual memory subsystem
 -----------------------------------------------
-
-The files  in  this directory can be used to tune the operation of the virtual
-memory (VM)  subsystem  of  the  Linux  kernel.  In addition, one of the files
-(bdflush) has some influence on disk usage.
-
-bdflush
--------
-
-This file  controls  the  operation of the bdflush kernel daemon. It currently
-contains nine  integer  values,  six of which are actually used by the kernel.
-They are listed in table 2-2.
-
-
-Table 2-2: Parameters in /proc/sys/vm/bdflush 
-..............................................................................
- Value      Meaning                                                            
- nfract     Percentage of buffer cache dirty to activate bdflush              
- ndirty     Maximum number of dirty blocks to  write out per wake-cycle        
- dummy      Unused                                                             
- dummy      Unused                                                             
- interval   jiffies delay between kupdate flushes
- age_buffer Time for normal buffer to age before we flush it                   
- nfract_sync Percentage of buffer cache dirty to activate bdflush synchronously
- nfract_stop_bdflush Percetange of buffer cache dirty to stop bdflush
- dummy      Unused                                                             
-..............................................................................
-
-nfract
-------
-
-This parameter  governs  the  maximum  number  of  dirty buffers in the buffer
-cache. Dirty means that the contents of the buffer still have to be written to
-disk (as  opposed  to  a  clean  buffer,  which  can just be forgotten about).
-Setting this  to  a  higher value means that Linux can delay disk writes for a
-long time, but it also means that it will have to do a lot of I/O at once when
-memory becomes short. A lower value will spread out disk I/O more evenly.
-
-interval
---------
-
-The interval between two kupdate runs. The value is expressed in
-jiffies (clockticks),  the  number of jiffies per second is 100.
-
-ndirty
-------
-
-Ndirty gives the maximum number of dirty buffers that bdflush can write to the
-disk at  one  time.  A high value will mean delayed, bursty I/O, while a small
-value can lead to memory shortage when bdflush isn't woken up often enough.
-
-age_buffer
-----------
-
-Finally, the age_buffer parameter govern the maximum time Linux
-waits before  writing  out  a  dirty buffer to disk. The value is expressed in
-jiffies (clockticks),  the  number of jiffies per second is 100.
-
-nfract_sync
------------
-
-nfract_stop_bdflush
--------------------
-
-buffermem
----------
-
-The three  values  in  this  file  control  how much memory should be used for
-buffer memory.  The  percentage  is calculated as a percentage of total system
-memory.
-
-The values are:
-
-min_percent
------------
-
-This is  the  minimum  percentage  of  memory  that  should be spent on buffer
-memory.
-
-borrow_percent
---------------
-
-When Linux is short on memory, and the buffer cache uses more than it has been
-allotted, the  memory  management  (MM)  subsystem will prune the buffer cache
-more heavily than other memory to compensate.
-
-max_percent
------------
-
-This is the maximum amount of memory that can be used for buffer memory.
-
-freepages
----------
-
-This file contains three values: min, low and high:
-
-min
----
-When the  number  of  free  pages  in the system reaches this number, only the
-kernel can allocate more memory.
-
-low
----
-If the number of free pages falls below this point, the kernel starts swapping
-aggressively.
-
-high
-----
-The kernel  tries  to  keep  up to this amount of memory free; if memory falls
-below this point, the kernel starts gently swapping in the hopes that it never
-has to do really aggressive swapping.
-
-kswapd
-------
-
-Kswapd is  the  kernel  swap  out daemon. That is, kswapd is that piece of the
-kernel that  frees  memory when it gets fragmented or full. Since every system
-is different, you'll probably want some control over this piece of the system.
-
-The file contains three numbers:
-
-tries_base
-----------
-
-The maximum  number  of  pages kswapd tries to free in one round is calculated
-from this  number.  Usually  this  number  will  be  divided  by  4  or 8 (see
-mm/vmscan.c), so it isn't as big as it looks.
-
-When you  need to increase the bandwidth to/from swap, you'll want to increase
-this number.
-
-tries_min
----------
-
-This is  the  minimum number of times kswapd tries to free a page each time it
-is called. Basically it's just there to make sure that kswapd frees some pages
-even when it's being called with minimum priority.
-
-swap_cluster
-------------
-
-This is probably the greatest influence on system performance.
-
-swap_cluster is  the  number  of  pages kswapd writes in one turn. You'll want
-this value  to  be  large  so that kswapd does its I/O in large chunks and the
-disk doesn't  have  to  seek  as  often, but you don't want it to be too large
-since that would flood the request queue.
-
-overcommit_memory
------------------
-
-This file  contains  one  value.  The following algorithm is used to decide if
-there's enough  memory:  if  the  value of overcommit_memory is positive, then
-there's always  enough  memory. This is a useful feature, since programs often
-malloc() huge  amounts  of  memory 'just in case', while they only use a small
-part of  it.  Leaving  this value at 0 will lead to the failure of such a huge
-malloc(), when in fact the system has enough memory for the program to run.
-
-On the  other  hand,  enabling this feature can cause you to run out of memory
-and thrash the system to death, so large and/or important servers will want to
-set this value to 0.
-
-pagecache
----------
-
-This file  does exactly the same job as buffermem, only this file controls the
-amount of memory allowed for memory mapping and generic caching of files.
-
-You don't  want  the  minimum level to be too low, otherwise your system might
-thrash when memory is tight or fragmentation is high.
-
-pagetable_cache
----------------
-
-The kernel  keeps a number of page tables in a per-processor cache (this helps
-a lot  on  SMP systems). The cache size for each processor will be between the
-low and the high value.
-
-On a  low-memory,  single  CPU system, you can safely set these values to 0 so
-you don't  waste  memory.  It  is  used  on SMP systems so that the system can
-perform fast  pagetable allocations without having to acquire the kernel memory
-lock.
-
-For large  systems,  the  settings  are probably fine. For normal systems they
-won't hurt  a  bit.  For  small  systems  (  less  than  16MB ram) it might be
-advantageous to set both values to 0.
-
-swapctl
--------
-
-This file  contains  no less than 8 variables. All of these values are used by
-kswapd.
-
-The first four variables
-* sc_max_page_age,
-* sc_page_advance,
-* sc_page_decline and
-* sc_page_initial_age
-are used  to  keep  track  of  Linux's page aging. Page aging is a bookkeeping
-method to  track  which pages of memory are often used, and which pages can be
-swapped out without consequences.
-
-When a  page  is  swapped in, it starts at sc_page_initial_age (default 3) and
-when the  page  is  scanned  by  kswapd,  its age is adjusted according to the
-following scheme:
-
-* If  the  page  was used since the last time we scanned, its age is increased
-  by sc_page_advance  (default  3).  Where  the  maximum  value  is  given  by
-  sc_max_page_age (default 20).
-* Otherwise  (meaning  it wasn't used) its age is decreased by sc_page_decline
-  (default 1).
-
-When a page reaches age 0, it's ready to be swapped out.
-
-The variables  sc_age_cluster_fract, sc_age_cluster_min, sc_pageout_weight and
-sc_bufferout_weight, can  be  used  to  control  kswapd's  aggressiveness  in
-swapping out pages.
-
-Sc_age_cluster_fract is used to calculate how many pages from a process are to
-be scanned by kswapd. The formula used is
-
-(sc_age_cluster_fract divided by 1024) times resident set size
-
-So if you want kswapd to scan the whole process, sc_age_cluster_fract needs to
-have a  value  of  1024.  The  minimum  number  of  pages  kswapd will scan is
-represented by sc_age_cluster_min, which is done so that kswapd will also scan
-small processes.
-
-The values  of  sc_pageout_weight  and sc_bufferout_weight are used to control
-how many  tries  kswapd  will make in order to swap out one page/buffer. These
-values can  be used to fine-tune the ratio between user pages and buffer/cache
-memory. When  you find that your Linux system is swapping out too many process
-pages in  order  to  satisfy  buffer  memory  demands,  you may want to either
-increase sc_bufferout_weight, or decrease the value of sc_pageout_weight.
+Please read Documentation/sysctl/vm.txt
 
 2.5 /proc/sys/dev - Device specific parameters
 ----------------------------------------------
@@ -1786,10 +1554,3 @@ need to  recompile  the kernel, or even 
 command to write value into these files, thereby changing the default settings
 of the kernel.
 ------------------------------------------------------------------------------
-
-
-
-
-
-
-
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/Documentation/mips/time.README linux-2.4.29-pre3/Documentation/mips/time.README
--- linux-2.4.28/Documentation/mips/time.README	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.29-pre3/Documentation/mips/time.README	2004-12-22 16:05:51.033661032 +0000
@@ -30,6 +30,7 @@ So we allow boards using 
 However, it is expected every board will move to the new time.c in the near
 future.
 
+In Linux 2.5 and Linux 2.4.26 CONFIG_OLD_TIME_C was removed.
 
 WHAT THE NEW CODE PROVIDES?
 --------------------------- 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/Documentation/networking/dl2k.txt linux-2.4.29-pre3/Documentation/networking/dl2k.txt
--- linux-2.4.28/Documentation/networking/dl2k.txt	2002-11-28 23:53:08.000000000 +0000
+++ linux-2.4.29-pre3/Documentation/networking/dl2k.txt	2004-12-22 16:07:10.839528696 +0000
@@ -1,7 +1,7 @@
 
     D-Link DL2000-based Gigabit Ethernet Adapter Installation
     for Linux
-    May 23, 2002
+    Oct 3, 2002
 
 Contents
 ========
@@ -19,7 +19,9 @@ Compatibility List
 Adapter Support:
 
 D-Link DGE-550T Gigabit Ethernet Adapter.
+D-Link DGE-510T Gigabit Ethernet Adapter.
 D-Link DGE-550SX Gigabit Ethernet Adapter.
+D-Link DGE-570T 2 Port Giga Ethernet Server Adapter.
 D-Link DL2000-based Gigabit Ethernet Adapter.
 
 
@@ -30,7 +32,8 @@ on the environments below.
  . Red Hat v7.0 (update kernel to 2.4.7)
  . Red Hat v7.1 (kernel 2.4.7)
  . Red Hat v7.2 (kernel 2.4.7-10)
-
+ . Red Hat v7.3 (kernel 2.4.18-3)
+ . Red Hat v8.0 (kernel 2.4.18-14)
 
 Quick Install
 =============
@@ -77,8 +80,8 @@ CD-ROM drive
 [root@XXX /] cd root
 [root@XXX /root] mkdir dl2k
 [root@XXX /root] cd dl2k
-[root@XXX dl2k] cp /cdrom/linux/dl2k.tgz /root/dl2k
-[root@XXX dl2k] tar xfvz dl2k.tgz
+[root@XXX dl2k] cp /cdrom/linux/dl2k-xx.tgz /root/dl2k
+[root@XXX dl2k] tar xfvz dl2k-xx.tgz (xx refer to release version)
 [root@XXX dl2k] make all
 
 Floppy disc drive
@@ -87,8 +90,8 @@ Floppy disc drive
 [root@XXX /] cd root
 [root@XXX /root] mkdir dl2k
 [root@XXX /root] cd dl2k
-[root@XXX dl2k] mcopy a:/linux/dl2k.tgz /root/dl2k
-[root@XXX dl2k] tar xfvz dl2k.tgz
+[root@XXX dl2k] mcopy a:/linux/dl2k-xx.tgz /root/dl2k
+[root@XXX dl2k] tar xfvz dl2k-xx.tgz (xx refer to release version)
 [root@XXX dl2k] make all
 
 Installing the Driver
@@ -134,7 +137,7 @@ Installing the Driver
 
   ifdown eth0
   ifconfig eth0 down
-  rmmod dl2k.o
+  rmmod dl2k
 
   The following are the commands to list the currently loaded modules and
   to see the current network configuration.
@@ -188,8 +191,8 @@ media=media_type		- Specifies the media 
 				  10mbps_fd	10Mbps full duplex.
 				  100mbps_hd	100Mbps half duplex.
 				  100mbps_fd	100Mbps full duplex.
-				  1000mbps_fd	1000Mbps full duplex.
 				  1000mbps_hd	1000Mbps half duplex.
+				  1000mbps_fd	1000Mbps full duplex.
 				  0		Autosensing active media.
 				  1		10Mbps half duplex.
 				  2		10Mbps full duplex.
@@ -198,9 +201,9 @@ media=media_type		- Specifies the media 
 				  5          	1000Mbps half duplex.
 				  6          	1000Mbps full duplex.
 
-				  By default, the NIC operates at autosense.
-				  1000mbps_fd and 1000mbps_hd types are only
-				  available for fiber adapter.
+				  By default, the NIC operates at Autosense.
+				  Fiber adapter only support Autosense and 
+				  1000Mbps full duplex types.
 
 vlan=n				- Specifies the VLAN ID. If vlan=0, the
 				  Virtual Local Area Network (VLAN) function is
@@ -214,25 +217,6 @@ jumbo=[0|1]			- Specifies the jumbo fram
 				  This feature need jumbo frame compatible 
 				  remote.
 				  
-rx_coalesce=m			- Number of rx frame handled each interrupt.
-rx_timeout=n			- Rx DMA wait time for an interrupt. 
-				  If set rx_coalesce > 0, hardware only assert 
-				  an interrupt for m frames. Hardware won't 
-				  assert rx interrupt until m frames received or
-				  reach timeout of n * 640 nano seconds. 
-				  Set proper rx_coalesce and rx_timeout can 
-				  reduce congestion collapse and overload which
-				  has been a bottlenect for high speed network.
-				  
-				  For example, rx_coalesce=10 rx_timeout=800.
-				  that is, hardware assert only 1 interrupt 
-				  for 10 frames received or timeout of 512 us. 
-
-tx_coalesce=n			- Number of tx frame handled each interrupt.
-				  Set n > 1 can reduce the interrupts 
-				  congestion usually lower performance of
-				  high speed network card. Default is 16.
-				  
 tx_flow=[1|0]			- Specifies the Tx flow control. If tx_flow=0, 
 				  the Tx flow control disable else driver
 				  autodetect.
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/Documentation/networking/e1000.txt linux-2.4.29-pre3/Documentation/networking/e1000.txt
--- linux-2.4.28/Documentation/networking/e1000.txt	2003-06-13 14:51:29.000000000 +0000
+++ linux-2.4.29-pre3/Documentation/networking/e1000.txt	2004-12-22 16:06:46.910166512 +0000
@@ -1,7 +1,7 @@
 Linux* Base Driver for the Intel(R) PRO/1000 Family of Adapters
 ===============================================================
 
-January 8, 2003
+September 13, 2004
 
 
 Contents
@@ -20,62 +20,29 @@ In This Release
 ===============
 
 This file describes the Linux* Base Driver for the Intel(R) PRO/1000 Family
-of Adapters, version 5.0.x.  This driver includes support for 
-Itanium(TM)-based systems.
+of Adapters, version 5.x.x.  This driver includes support for Itanium(TM)2 
+and EM64T systems.
 
+For questions related to hardware requirements, refer to the documentation 
+supplied with your Intel PRO/1000 adapter. All hardware requirements listed 
+apply to use with Linux.
 
+Native VLANs are now available with supported kernels.
 
-
-Supported Adapters
-==================
-
-The following Intel network adapters are compatible with the drivers in this 
-release:
-
-   Controller  Adapter Name                         Board IDs
-   ----------  ------------                         ---------
-
-   82542       PRO/1000 Gigabit Server Adapter      700262-xxx, 717037-xxx
-
-   82543       PRO/1000 F Server Adapter            738640-xxx, A38888-xxx
-
-   82543       PRO/1000 T Server Adapter            A19845-xxx, A33948-xxx
-
-   82544       PRO/1000 XT Server Adapter           A51580-xxx
-
-   82544       PRO/1000 XF Server Adapter           A50484-xxx
-
-   82544       PRO/1000 T Desktop Adapter           A62947-xxx
-
-   82540       PRO/1000 MT Desktop Adapter          A78408-xxx
-   82541                                            C91016-xxx
-
-   82545       PRO/1000 MT Server Adapter           A92165-xxx
-
-   82546       PRO/1000 MT Dual Port Server Adapter A92111-xxx
-
-   82545       PRO/1000 MF Server Adapter           A91622-xxx
-
-   82545       PRO/1000 MF Server Adapter(LX)       A91624-xxx
-
-   82546       PRO/1000 MF Dual Port Server Adapter A91620-xxx
-
-
-
-To verify your Intel adapter is supported, find the board ID number on the 
-adapter. Look for a label that has a barcode and a number in the format  
-A12345-001. Match this to the list of numbers above.
+Identifying Your Adapter
+========================
 
 For more information on how to identify your adapter, go to the Adapter & 
 Driver ID Guide at:
 
     http://support.intel.com/support/network/adapter/pro100/21397.htm
 
-For the latest Intel network drivers for Linux, refer to the following
+For the latest Intel network drivers for Linux, refer to the following 
+website. In the search field, enter your adapter name or type, or use the 
+networking link on the left to search for your adapter:
 
     http://downloadfinder.intel.com/scripts-df/support_intel.asp
 
-
 Command Line Parameters
 =======================
 
@@ -91,15 +58,25 @@ For example, with two PRO/1000 PCI adapt
 
      insmod e1000 TxDescriptors=80,128
 
-loads the e1000 driver with 80 TX resources for the first adapter and 128 TX 
-resources for the second adapter.
+loads the e1000 driver with 80 TX descriptors for the first adapter and 128 TX 
+descriptors for the second adapter.
 
 The default value for each parameter is generally the recommended setting,
-unless otherwise noted.
-
-For more information about the AutoNeg, Duplex, and Speed parameters, see the
-"Speed and Duplex Configuration" section in this document.
+unless otherwise noted. Also, if the driver is statically built into the
+kernel, the driver is loaded with the default values for all the parameters.
+Ethtool can be used to change some of the parameters at runtime.
+
+    NOTES: For more information about the AutoNeg, Duplex, and Speed
+           parameters, see the "Speed and Duplex Configuration" section in 
+           this document.
+
+           For more information about the InterruptThrottleRate, RxIntDelay, 
+           TxIntDelay, RxAbsIntDelay, and TxAbsIntDelay parameters, see the 
+           application note at:
+           http://www.intel.com/design/network/applnots/ap450.htm
 
+           A descriptor describes a data buffer and attributes related to the 
+           data buffer. This information is accessed by the hardware.
 
 AutoNeg (adapters using copper connections only)
 Valid Range: 0x01-0x0F, 0x20-0x2F
@@ -107,11 +84,13 @@ Default Value: 0x2F
     This parameter is a bit mask that specifies which speed and duplex
     settings the board advertises. When this parameter is used, the Speed and
     Duplex parameters must not be specified.  
+    NOTE: Refer to the Speed and Duplex section of this readme for more 
+          information on the AutoNeg parameter.
 
 Duplex (adapters using copper connections only)
 Valid Range: 0-2 (0=auto-negotiate, 1=half, 2=full)
 Default Value: 0
-    Defines the direction in which data is allowed to flow. Can by either one 
+    Defines the direction in which data is allowed to flow. Can be either one 
     or two-directional. If both Duplex and the link partner are set to auto-
     negotiate, the board auto-detects the correct duplex. If the link partner
     is forced (either full or half), Duplex defaults to half-duplex.
@@ -124,22 +103,46 @@ Default: Read flow control settings from
 
 InterruptThrottleRate
 Valid Range: 100-100000 (0=off, 1=dynamic)
-Default Value: 1
+Default Value: 8000
     This value represents the maximum number of interrupts per second the 
     controller generates. InterruptThrottleRate is another setting used in 
     interrupt moderation. Dynamic mode uses a heuristic algorithm to adjust 
     InterruptThrottleRate based on the current traffic load.
+Un-supported Adapters: InterruptThrottleRate is NOT supported by 82542, 82543
+    or 82544-based adapters.
 
     NOTE: InterruptThrottleRate takes precedence over the TxAbsIntDelay and 
           RxAbsIntDelay parameters. In other words, minimizing the receive 
           and/or transmit absolute delays does not force the controller to 
           generate more interrupts than what the Interrupt Throttle Rate 
           allows.
+    CAUTION: If you are using the Intel PRO/1000 CT Network Connection 
+             (controller 82547), setting InterruptThrottleRate to a value 
+             greater than 75,000, may hang (stop transmitting) adapters under 
+             certain network conditions. If this occurs a NETDEV WATCHDOG 
+             message is logged in the system event log. In addition, the 
+             controller is automatically reset, restoring the network 
+             connection. To eliminate the potential for the hang, ensure 
+             that InterruptThrottleRate is set no greater than 75,000 and is 
+             not set to 0.
+    NOTE: When e1000 is loaded with default settings and multiple adapters are 
+          in use simultaneously, the CPU utilization may increase non-linearly. 
+          In order to limit the CPU utilization without impacting the overall 
+          throughput, we recommend that you load the driver as follows:
+
+              insmod e1000.o InterruptThrottleRate=3000,3000,3000
+
+          This sets the InterruptThrottleRate to 3000 interrupts/sec for the 
+          first, second, and third instances of the driver. The range of 2000 to 
+          3000 interrupts per second works on a majority of systems and is a 
+          good starting point, but the optimal value will be platform-specific. 
+          If CPU utilization is not a concern, use RX_POLLING (NAPI) and default 
+          driver settings.
 
 RxDescriptors
 Valid Range: 80-256 for 82542 and 82543-based adapters
-             80-4096 for 82540, 82544, 82545, and 82546-based adapters
-Default Value: 80
+             80-4096 for all other supported adapters
+Default Value: 256
     This value is the number of receive descriptors allocated by the driver. 
     Increasing this value allows the driver to buffer more incoming packets. 
     Each descriptor is 16 bytes.  A receive buffer is also allocated for each
@@ -148,6 +151,9 @@ Default Value: 80
 
     NOTE: MTU designates the frame size. It only needs to be set for Jumbo 
           Frames.
+    NOTE: Depending on the available system resources, the request for a
+    higher number of receive descriptors may be denied.  In this case,
+    use a lower number.
 
 RxIntDelay
 Valid Range: 0-65535 (0=off)
@@ -167,11 +173,11 @@ Default Value: 0
              restoring the network connection. To eliminate the potential for
              the hang ensure that RxIntDelay is set to 0.
 
-RxAbsIntDelay (82540, 82545, and 82546-based adapters only)
+RxAbsIntDelay (82540, 82545 and later adapters only)
 Valid Range: 0-65535 (0=off)
 Default Value: 128
     This value, in units of 1.024 microseconds, limits the delay in which a 
-    transmit interrupt is generated. Useful only if RxIntDelay is non-zero, 
+    receive interrupt is generated. Useful only if RxIntDelay is non-zero, 
     this value ensures that an interrupt is generated after the initial 
     packet is received within the set amount of time.  Proper tuning,
     along with RxIntDelay, may improve traffic throughput in specific network
@@ -187,12 +193,16 @@ Default Value: 0 (auto-negotiate at all 
 
 TxDescriptors
 Valid Range: 80-256 for 82542 and 82543-based adapters
-             80-4096 for 82540, 82544, 82545, and 82546-based adapters
+             80-4096 for all other supported adapters
 Default Value: 256
     This value is the number of transmit descriptors allocated by the driver.
     Increasing this value allows the driver to queue more transmits. Each 
     descriptor is 16 bytes.
 
+    NOTE: Depending on the available system resources, the request for a
+    higher number of transmit descriptors may be denied.  In this case,
+    use a lower number.
+
 TxIntDelay
 Valid Range: 0-65535 (0=off)
 Default Value: 64
@@ -202,7 +212,7 @@ Default Value: 64
     system is reporting dropped transmits, this value may be set too high
     causing the driver to run out of available transmit descriptors.
 
-TxAbsIntDelay (82540, 82545, and 82546-based adapters only)
+TxAbsIntDelay (82540, 82545 and later adapters only)
 Valid Range: 0-65535 (0=off)
 Default Value: 64
     This value, in units of 1.024 microseconds, limits the delay in which a 
@@ -218,7 +228,6 @@ Default Value: 1
     A value of '1' indicates that the driver should enable IP checksum
     offload for received packets (both UDP and TCP) to the adapter hardware.
 
-
 Speed and Duplex Configuration
 ==============================
 
@@ -250,6 +259,10 @@ Bit            7      6      5       4  
 Speed (Mbps)   N/A    N/A    1000    N/A     100    100    10      10
 Duplex                       Full            Full   Half   Full    Half
 
+For example to limit the negotiated speed/duplex on the interface to 10 Mbps 
+Half or Full duplex, set AutoNeg to 0x02: 
+    insmod e1000 AutoNeg=0x02
+
 Note that setting AutoNeg does not guarantee that the board will link at the 
 highest specified speed or duplex mode, but the board will link at the 
 highest possible speed/duplex of the link partner IF the link partner is also
@@ -260,6 +273,38 @@ adapter MUST be forced to the same speed
 Additional Configurations
 =========================
 
+  Configuring the Driver on Different Distributions
+  -------------------------------------------------
+
+  Configuring a network driver to load properly when the system is started is
+  distribution dependent. Typically, the configuration process involves adding
+  an alias line to /etc/modules.conf as well as editing other system startup 
+  scripts and/or configuration files. Many popular Linux distributions ship 
+  with tools to make these changes for you. To learn the proper way to 
+  configure a network device for your system, refer to your distribution 
+  documentation. If during this process you are asked for the driver or module 
+  name, the name for the Linux Base Driver for the Intel PRO/1000 Family of 
+  Adapters is e1000.
+
+  As an example, if you install the e1000 driver for two PRO/1000 adapters 
+  (eth0 and eth1) and set the speed and duplex to 10full and 100half, add the 
+  following to modules.conf:
+
+       alias eth0 e1000
+       alias eth1 e1000
+       options e1000 Speed=10,100 Duplex=2,1
+
+  Viewing Link Messages
+  ---------------------
+
+  Link messages will not be displayed to the console if the distribution is 
+  restricting system messages. In order to see network driver link messages on 
+  your console, set dmesg to eight by entering the following:
+
+       dmesg -n 8
+
+  NOTE: This setting is not saved across reboots.
+
   Jumbo Frames
   ------------
 
@@ -277,6 +322,51 @@ Additional Configurations
   10 or 100 Mbps may result in poor performance or loss of link.
 
 
+  NOTE: MTU designates the frame size. To enable Jumbo Frames, increase the
+  MTU size on the interface beyond 1500.
+
+  Ethtool
+  -------
+
+  The driver utilizes the ethtool interface for driver configuration and
+  diagnostics, as well as displaying statistical information.  Ethtool
+  version 1.6 or later is required for this functionality.
+
+  The latest release of ethtool can be found from
+  http://sf.net/projects/gkernel.  After ethtool is installed,
+  ethtool-copy.h must be copied and renamed to ethtool.h in your kernel
+  source tree at <linux_kernel_src>/include/linux.  Backup the original
+  ethtool.h as needed before copying.  The driver then must be recompiled
+  in order to take advantage of the latest ethtool features.
+
+  NOTE: Ethtool 1.6 only supports a limited set of ethtool options. Support 
+  for a more complete ethtool feature set can be enabled by upgrading 
+  ethtool to ethtool-1.8.1. 
+
+  Enabling Wake on LAN* (WoL)
+  ---------------------------
+
+  WoL is configured through the Ethtool* utility. Ethtool is included with
+  all versions of Red Hat after Red Hat 7.2. For other Linux distributions, 
+  download and install Ethtool from the following website: 
+  http://sourceforge.net/projects/gkernel.
+
+  For instructions on enabling WoL with Ethtool, refer to the website listed 
+  above.
+
+  WoL will be enabled on the system during the next shut down or reboot. 
+  For this driver version, in order to enable WoL, the e1000 driver must be 
+  loaded when shutting down or rebooting the system.
+
+  NAPI
+  ----
+
+  NAPI (Rx polling mode) is supported in the e1000 driver. NAPI is enabled
+  or disabled based on the configuration of the kernel. 
+
+  See www.cyberus.ca/~hadi/usenix-paper.tgz for more information on NAPI.
+
+
 Known Issues
 ============
 
@@ -284,9 +374,9 @@ Known Issues
   -------------------------------
 
   Memory allocation failures have been observed on Linux systems with 64 MB 
-  of RAM or less that are running Jumbo Frames. If you are using Jumbo 
-  Frames, your system may require more than the advertised minimum 
-  requirement of 64 MB of system memory.
+  of RAM or less that are running Jumbo Frames. If you are using Jumbo Frames,
+  your system may require more than the advertised minimum requirement of 64 MB
+  of system memory.
 
 
 Support
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/Documentation/parport.txt linux-2.4.29-pre3/Documentation/parport.txt
--- linux-2.4.28/Documentation/parport.txt	2001-11-09 22:30:55.000000000 +0000
+++ linux-2.4.29-pre3/Documentation/parport.txt	2004-12-22 16:07:02.293827840 +0000
@@ -264,5 +264,5 @@ the DMA channel, and try with:
     io=0x378 irq=7 dma=none (for PIO)
     io=0x378 irq=7 dma=3 (for DMA)
 --
-Philip.Blundell@pobox.com
+philb@gnu.org
 tim@cyberelk.net
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/Documentation/sysctl/vm.txt linux-2.4.29-pre3/Documentation/sysctl/vm.txt
--- linux-2.4.28/Documentation/sysctl/vm.txt	2002-11-28 23:53:08.000000000 +0000
+++ linux-2.4.29-pre3/Documentation/sysctl/vm.txt	2004-12-22 16:07:16.454675064 +0000
@@ -1,146 +1,143 @@
-Documentation for /proc/sys/vm/*	kernel version 2.4.19
-	(c) 1998, 1999,  Rik van Riel <riel@nl.linux.org>
+Documentation for /proc/sys/vm/*	Kernel version 2.4.28
+=============================================================
+
+ (c) 1998, 1999, Rik van Riel <riel@nl.linux.org>
+    - Initial version
+
+ (c) 2004, Marc-Christian Petersen <m.c.p@linux-systeme.com>
+    - Removed non-existent knobs which were removed in early
+      2.4 stages
+    - Corrected values for bdflush
+    - Documented missing tunables
+    - Documented aa-vm tunables
 
-For general info and legal blurb, please look in README.
 
-==============================================================
+
+For general info and legal blurb, please look in README.
+=============================================================
 
 This file contains the documentation for the sysctl files in
-/proc/sys/vm and is valid for Linux kernel version 2.4.
+/proc/sys/vm and is valid for Linux kernel v2.4.28.
 
 The files in this directory can be used to tune the operation
 of the virtual memory (VM) subsystem of the Linux kernel, and
-one of the files (bdflush) also has a little influence on disk
-usage.
+three of the files (bdflush, max-readahead, min-readahead)
+also have some influence on disk usage.
 
 Default values and initialization routines for most of these
-files can be found in mm/swap.c.
+files can be found in mm/vmscan.c, mm/page_alloc.c and
+mm/filemap.c.
 
 Currently, these files are in /proc/sys/vm:
 - bdflush
-- buffermem
-- freepages
+- block_dump
 - kswapd
+- laptop_mode
+- max-readahead
+- min-readahead
 - max_map_count
 - overcommit_memory
 - page-cluster
-- pagecache
 - pagetable_cache
+- vm_anon_lru
+- vm_cache_scan_ratio
+- vm_gfp_debug
+- vm_lru_balance_ratio
+- vm_mapped_ratio
+- vm_passes
+- vm_vfs_scan_ratio
+=============================================================
 
-==============================================================
 
-bdflush:
 
+bdflush:
+--------
 This file controls the operation of the bdflush kernel
 daemon. The source code to this struct can be found in
-linux/fs/buffer.c. It currently contains 9 integer values,
+fs/buffer.c. It currently contains 9 integer values,
 of which 6 are actually used by the kernel.
 
-From linux/fs/buffer.c:
---------------------------------------------------------------
-union bdflush_param {
-	struct {
-		int nfract;	/* Percentage of buffer cache dirty to
-				   activate bdflush */
-		int ndirty;	/* Maximum number of dirty blocks to write out per
-				   wake-cycle */
-		int dummy2;	/* old "nrefill" */
-		int dummy3;	/* unused */
-		int interval;	/* jiffies delay between kupdate flushes */
-		int age_buffer;	/* Time for normal buffer to age before we flush it */
-		int nfract_sync;/* Percentage of buffer cache dirty to
-				   activate bdflush synchronously */
-		int nfract_stop_bdflush; /* Percentage of buffer cache dirty to stop bdflush */
-		int dummy5;	/* unused */
-	} b_un;
-	unsigned int data[N_PARAM];
-} bdf_prm = {{30, 500, 0, 0, 5*HZ, 30*HZ, 60, 20, 0}};
---------------------------------------------------------------
-
-int nfract:
-The first parameter governs the maximum number of dirty
-buffers in the buffer cache. Dirty means that the contents
-of the buffer still have to be written to disk (as opposed
-to a clean buffer, which can just be forgotten about).
-Setting this to a high value means that Linux can delay disk
-writes for a long time, but it also means that it will have
-to do a lot of I/O at once when memory becomes short. A low
-value will spread out disk I/O more evenly, at the cost of
-more frequent I/O operations.  The default value is 30%,
-the minimum is 0%, and the maximum is 100%.
-
-int ndirty:
-The second parameter (ndirty) gives the maximum number of
-dirty buffers that bdflush can write to the disk in one time.
-A high value will mean delayed, bursty I/O, while a small
-value can lead to memory shortage when bdflush isn't woken
-up often enough.
-
-int interval:
-The fifth parameter, interval, is the minimum rate at
-which kupdate will wake and flush.  The value is expressed in
-jiffies (clockticks), the number of jiffies per second is
-normally 100 (Alpha is 1024). Thus, x*HZ is x seconds.  The
-default value is 5 seconds, the minimum is 0 seconds, and the
-maximum is 600 seconds.
-
-int age_buffer:
-The sixth parameter, age_buffer, governs the maximum time
-Linux waits before writing out a dirty buffer to disk.  The
-value is in jiffies.  The default value is 30 seconds,
-the minimum is 1 second, and the maximum 6,000 seconds.
-
-int nfract_sync:
-The seventh parameter, nfract_sync, governs the percentage
-of buffer cache that is dirty before bdflush activates
-synchronously.  This can be viewed as the hard limit before
-bdflush forces buffers to disk.  The default is 60%, the
-minimum is 0%, and the maximum is 100%.
-
-int nfract_stop_bdflush:
-The eighth parameter, nfract_stop_bdflush, governs the percentage
-of buffer cache that is dirty which will stop bdflush.
-The default is 20%, the miniumum is 0%, and the maxiumum is 100%.
-==============================================================
-buffermem:
-
-The three values in this file correspond to the values in
-the struct buffer_mem. It controls how much memory should
-be used for buffer memory. The percentage is calculated
-as a percentage of total system memory.
-
-The values are:
-min_percent	-- this is the minimum percentage of memory
-		   that should be spent on buffer memory
-borrow_percent  -- UNUSED
-max_percent     -- UNUSED
-
-==============================================================
-freepages:
-
-This file contains the values in the struct freepages. That
-struct contains three members: min, low and high.
-
-The meaning of the numbers is:
-
-freepages.min	When the number of free pages in the system
-		reaches this number, only the kernel can
-		allocate more memory.
-freepages.low	If the number of free pages gets below this
-		point, the kernel starts swapping aggressively.
-freepages.high	The kernel tries to keep up to this amount of
-		memory free; if memory comes below this point,
-		the kernel gently starts swapping in the hopes
-		that it never has to do real aggressive swapping.
+nfract:		The first parameter governs the maximum
+		number of dirty buffers in the buffer
+		cache. Dirty means that the contents of the
+		buffer still have to be written to disk (as
+		opposed to a clean buffer, which can just be
+		forgotten about). Setting this to a high
+		value means that Linux can delay disk writes
+		for a long time, but it also means that it
+		will have to do a lot of I/O at once when
+		memory becomes short. A low value will
+		spread out disk I/O more evenly, at the cost
+		of more frequent I/O operations. The default
+		value is 30%, the minimum is 0%, and the
+		maximum is 100%.
+
+ndirty:		The second parameter (ndirty) gives the
+		maximum number of dirty buffers that bdflush
+		can write to the disk in one time. A high
+		value will mean delayed, bursty I/O, while a
+		small value can lead to memory shortage when
+		bdflush isn't woken up often enough. The
+		default value is 500 dirty buffers, the
+		minimum is 1, and the maximum is 50000.
+
+dummy2:		The third parameter is not used.
+
+dummy3:		The fourth parameter is not used.
+
+interval:	The fifth parameter, interval, is the minimum
+		rate at which kupdate will wake and flush.
+		The value is in jiffies (clockticks), the
+		number of jiffies per second is normally 100
+		(Alpha is 1024). Thus, x*HZ is x seconds. The
+		default value is 5 seconds, the minimum	is 0
+		seconds, and the maximum is 10,000 seconds.
+
+age_buffer:	The sixth parameter, age_buffer, governs the
+		maximum time Linux waits before writing out a
+		dirty buffer to disk. The value is in jiffies.
+		The default value is 30 seconds, the minimum
+		is 1 second, and the maximum 10,000 seconds.
+
+sync:		The seventh parameter, nfract_sync, governs
+		the percentage of buffer cache that is dirty
+		before bdflush activates synchronously. This
+		can be viewed as the hard limit before
+		bdflush forces buffers to disk. The default
+		is 60%,	the minimum is 0%, and the maximum
+		is 100%.
+
+stop_bdflush:	The eighth parameter, nfract_stop_bdflush,
+		governs the percentage of buffer cache that
+		is dirty which will stop bdflush. The default
+		is 20%, the miniumum is 0%, and the maxiumum
+		is 100%.
+
+dummy5:		The ninth parameter is not used.
+
+So the default is: 30 500 0 0 500 3000 60 20 0   for 100 HZ.
+=============================================================
+
+
+
+block_dump:
+-----------
+It can happen that the disk still keeps spinning up and you
+don't quite know why or what causes it. The laptop mode patch
+has a little helper for that as well. When set to 1, it will
+dump info to the kernel message buffer about what process
+caused the io. Be careful when playing with this setting.
+It is advisable to shut down syslog first! The default is 0.
+=============================================================
 
-==============================================================
 
-kswapd:
 
+kswapd:
+-------
 Kswapd is the kernel swapout daemon. That is, kswapd is that
 piece of the kernel that frees memory when it gets fragmented
-or full. Since every system is different, you'll probably want
-some control over this piece of the system.
+or full. Since every system is different, you'll probably
+want some control over this piece of the system.
 
 The numbers in this page correspond to the numbers in the
 struct pager_daemon {tries_base, tries_min, swap_cluster
@@ -152,39 +149,83 @@ tries_base	The maximum number of pages k
 		number. Usually this number will be divided
 		by 4 or 8 (see mm/vmscan.c), so it isn't as
 		big as it looks.
-		When you need to increase the bandwidth to/from
-		swap, you'll want to increase this number.
+		When you need to increase the bandwidth to/
+		from swap, you'll want to increase this
+		number.
+
 tries_min	This is the minimum number of times kswapd
 		tries to free a page each time it is called.
 		Basically it's just there to make sure that
 		kswapd frees some pages even when it's being
 		called with minimum priority.
+
 swap_cluster	This is the number of pages kswapd writes in
 		one turn. You want this large so that kswapd
 		does it's I/O in large chunks and the disk
-		doesn't have to seek often, but you don't want
-		it to be too large since that would flood the
-		request queue.
+		doesn't have to seek often, but you don't
+		want it to be too large since that would
+		flood the request queue.
+
+The default value is: 512 32 8.
+=============================================================
 
-==============================================================
 
-overcommit_memory:
 
-This value contains a flag that enables memory overcommitment.
-When this flag is 0, the kernel checks before each malloc()
-to see if there's enough memory left. If the flag is nonzero,
-the system pretends there's always enough memory.
+laptop_mode:
+------------
+Setting this to 1 switches the vm (and block layer) to laptop
+mode. Leaving it to 0 makes the kernel work like before. When
+in laptop mode, you also want to extend the intervals
+desribed in Documentation/laptop-mode.txt.
+See the laptop-mode.sh script for how to do that.
+
+The default value is 0.
+=============================================================
 
-This feature can be very useful because there are a lot of
-programs that malloc() huge amounts of memory "just-in-case"
-and don't use much of it.
 
-Look at: mm/mmap.c::vm_enough_memory() for more information.
 
-==============================================================
+max-readahead:
+--------------
+This tunable affects how early the Linux VFS will fetch the
+next block of a file from memory. File readahead values are
+determined on a per file basis in the VFS and are adjusted
+based on the behavior of the application accessing the file.
+Anytime the current position being read in a file plus the
+current read ahead value results in the file pointer pointing
+to the next block in the file, that block will be fetched
+from disk. By raising this value, the Linux kernel will allow
+the readahead value to grow larger, resulting in more blocks
+being prefetched from disks which predictably access files in
+uniform linear fashion. This can result in performance
+improvements, but can also result in excess (and often
+unnecessary) memory usage. Lowering this value has the
+opposite affect. By forcing readaheads to be less aggressive,
+memory may be conserved at a potential performance impact.
+
+The default value is 31.
+=============================================================
 
-max_map_count:
 
+
+min-readahead:
+--------------
+Like max-readahead, min-readahead places a floor on the
+readahead value. Raising this number forces a files readahead
+value to be unconditionally higher, which can bring about
+performance improvements, provided that all file access in
+the system is predictably linear from the start to the end of
+a file. This of course results in higher memory usage from
+the pagecache. Conversely, lowering this value, allows the
+kernel to conserve pagecache memory, at a potential
+performance cost.
+
+The default value is 3.
+=============================================================
+
+
+
+max_map_count:
+--------------
 This file contains the maximum number of memory map areas a
 process may have. Memory map areas are used as a side-effect
 of calling malloc, directly by mmap and mprotect, and also
@@ -194,10 +235,29 @@ While most applications need less than a
 certain programs, particularly malloc debuggers, may consume 
 lots of them, e.g. up to one or two maps per allocation.
 
-==============================================================
+The default value is 65536.
+=============================================================
 
-page-cluster:
 
+
+overcommit_memory:
+------------------
+This value contains a flag to enable memory overcommitment.
+When this flag is 0, the kernel checks before each malloc()
+to see if there's enough memory left. If the flag is nonzero,
+the system pretends there's always enough memory.
+
+This feature can be very useful because there are a lot of
+programs that malloc() huge amounts of memory "just-in-case"
+and don't use much of it. The default value is 0.
+
+Look at: mm/mmap.c::vm_enough_memory() for more information.
+=============================================================
+
+
+
+page-cluster:
+-------------
 The Linux VM subsystem avoids excessive disk seeks by reading
 multiple pages on a page fault. The number of pages it reads
 is dependent on the amount of memory in your machine.
@@ -205,29 +265,12 @@ is dependent on the amount of memory in 
 The number of pages the kernel reads in at once is equal to
 2 ^ page-cluster. Values above 2 ^ 5 don't make much sense
 for swap because we only cluster swap data in 32-page groups.
+=============================================================
 
-==============================================================
-
-pagecache:
-
-This file does exactly the same as buffermem, only this
-file controls the struct page_cache, and thus controls
-the amount of memory used for the page cache.
 
-In 2.2, the page cache is used for 3 main purposes:
-- caching read() data from files
-- caching mmap()ed data and executable files
-- swap cache
-
-When your system is both deep in swap and high on cache,
-it probably means that a lot of the swapped data is being
-cached, making for more efficient swapping than possible
-with the 2.0 kernel.
-
-==============================================================
 
 pagetable_cache:
-
+----------------
 The kernel keeps a number of page tables in a per-processor
 cache (this helps a lot on SMP systems). The cache size for
 each processor will be between the low and the high value.
@@ -241,3 +284,98 @@ For large systems, the settings are prob
 systems they won't hurt a bit. For small systems (<16MB ram)
 it might be advantageous to set both values to 0.
 
+The default value is: 25 50.
+=============================================================
+
+
+
+vm_anon_lru:
+------------
+select if to immdiatly insert anon pages in the lru.
+Immediatly means as soon as they're allocated during the page
+faults. If this is set to 0, they're inserted only after the
+first swapout.
+  
+Having anon pages immediatly inserted in the lru allows the
+VM to know better when it's worthwhile to start swapping
+anonymous ram, it will start to swap earlier and it should
+swap smoother and faster, but it will decrease scalability
+on the >16-ways of an order of magnitude. Big SMP/NUMA
+definitely can't take an hit on a global spinlock at
+every anon page allocation.
+
+Low ram machines that swaps all the time want to turn
+this on (i.e. set to 1).
+
+The default value is 0.
+=============================================================
+
+
+
+vm_cache_scan_ratio:
+--------------------
+is how much of the inactive LRU queue we will scan in one go.
+A value of 6 for vm_cache_scan_ratio implies that we'll scan
+1/6 of the inactive lists during a normal aging round.
+
+The default value is 6.
+=============================================================
+
+
+
+vm_gfp_debug:
+------------
+is when __alloc_pages fails, dump us a stack. This will
+mostly happen during OOM conditions (hopefully ;)
+
+The default value is 0.
+=============================================================
+
+
+
+vm_lru_balance_ratio:
+---------------------
+controls the balance between active and inactive cache. The
+bigger vm_balance is, the easier the active cache will grow,
+because we'll rotate the active list slowly. A value of 2
+means we'll go towards a balance of 1/3 of the cache being
+inactive.
+
+The default value is 2.
+=============================================================
+
+
+
+vm_mapped_ratio:
+----------------
+controls the pageout rate, the smaller, the earlier we'll
+start to pageout.
+
+The default value is 100.
+=============================================================
+
+
+
+vm_passes:
+----------
+is the number of vm passes before failing the memory
+balancing. Take into account 3 passes are needed for a
+flush/wait/free cycle and that we only scan
+1/vm_cache_scan_ratio of the inactive list at each pass.
+
+The default value is 60.
+=============================================================
+
+
+
+vm_vfs_scan_ratio:
+------------------
+is what proportion of the VFS queues we will scan in one go.
+A value of 6 for vm_vfs_scan_ratio implies that 1/6th of the
+unused-inode, dentry and dquot caches will be freed during a
+normal aging round.
+Big fileservers (NFS, SMB etc.) probably want to set this
+value to 3 or 2.
+
+The default value is 6.
+=============================================================
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/MAINTAINERS linux-2.4.29-pre3/MAINTAINERS
--- linux-2.4.28/MAINTAINERS	2004-12-22 16:17:15.568595904 +0000
+++ linux-2.4.29-pre3/MAINTAINERS	2004-12-22 16:07:01.323975280 +0000
@@ -80,7 +80,7 @@ S:	Maintained
 
 3C505 NETWORK DRIVER
 P:	Philip Blundell
-M:	Philip.Blundell@pobox.com
+M:	philb@gnu.org
 L:	linux-net@vger.kernel.org
 S:	Maintained
 
@@ -579,6 +579,11 @@ W:	http://linux-decnet.sourceforge.net
 L:	linux-decnet-user@lists.sourceforge.net
 S:	Maintained
 
+DEFXX FDDI NETWORK DRIVER
+P:	Maciej W. Rozycki
+M:	macro@linux-mips.org
+S:	Maintained
+
 DELL LAPTOP SMM DRIVER
 P:	Massimo Dal Zotto
 M:	dz@debian.org
@@ -694,7 +699,7 @@ S:	Maintained
 
 ETHEREXPRESS-16 NETWORK DRIVER
 P:	Philip Blundell
-M:	Philip.Blundell@pobox.com
+M:	philb@gnu.org
 L:	linux-net@vger.kernel.org
 S:	Maintained
 
@@ -971,11 +976,12 @@ W:	http://sourceforge.net/projects/e1000
 S:	Supported
 
 INTERMEZZO FILE SYSTEM
-P:	Chen Yang
-M:	intermezzo-devel@lists.sourceforge.net
+P:	Peter J. Braam
+M:	braam@clusterfs.com
 W:      http://www.inter-mezzo.org/
+W:	http://sourceforge.net/projects/intermezzo/
 L:      intermezzo-discuss@lists.sourceforge.net
-S:      Maintained
+S:	Orphan
 
 IOC3 DRIVER
 P:	Ralf Baechle
@@ -1415,13 +1421,13 @@ S:	Maintained
 
 PARALLEL PORT SUPPORT
 P:	Phil Blundell
-M:	Philip.Blundell@pobox.com
+M:	philb@gnu.org
 P:	Tim Waugh
 M:	tim@cyberelk.net
 P:	David Campbell
 M:	campbell@torque.net
 P:	Andrea Arcangeli
-M:	andrea@e-mind.com
+M:	andrea@suse.de
 L:	linux-parport@torque.net
 W:	http://people.redhat.com/twaugh/parport/
 S:	Maintained
@@ -1496,13 +1502,6 @@ L:	linux-mips@linux-mips.org
 W:	http://www.realitydiluted.com/projects/nino
 S:	Maintained
 
-PHILIPS NINO PALM PC
-P:	Steven Hill
-M:	sjhill@realitydiluted.com
-L:	linux-mips@oss.sgi.com
-W:	http://www.realitydiluted.com/projects/nino
-S:	Maintained
-
 PNP SUPPORT
 P:	Tom Lees
 M:	tom@lpsg.demon.co.uk
@@ -1775,11 +1774,6 @@ M:	jbglaw@lug-owl.de
 L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
-STALLION TECHNOLOGIES MULTIPORT SERIAL BOARDS
-M:	support@stallion.oz.au
-W:	http://www.stallion.com
-S:	Supported
-
 STARFIRE/DURALAN NETWORK DRIVER
 P:	Ion Badulescu
 M:	ionut@cs.columbia.edu
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/Makefile linux-2.4.29-pre3/Makefile
--- linux-2.4.28/Makefile	2004-12-22 16:17:15.573595144 +0000
+++ linux-2.4.29-pre3/Makefile	2004-12-22 16:07:09.566722192 +0000
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
-SUBLEVEL = 28
-EXTRAVERSION =
+SUBLEVEL = 29
+EXTRAVERSION = -pre3
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/cris/drivers/serial.c linux-2.4.29-pre3/arch/cris/drivers/serial.c
--- linux-2.4.28/arch/cris/drivers/serial.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/cris/drivers/serial.c	2004-12-22 16:07:10.313608648 +0000
@@ -3324,10 +3324,7 @@ do_softint(void *private_)
 		return;
 	
 	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup)(tty);
-		wake_up_interruptible(&tty->write_wait);
+		tty_wakeup(tty);
 	}
 }
 
@@ -3952,11 +3949,7 @@ rs_flush_buffer(struct tty_struct *tty)
 	info->xmit.head = info->xmit.tail = 0;
 	restore_flags(flags);
 
-	wake_up_interruptible(&tty->write_wait);
-
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
+	tty_wakeup(tty);
 }
 
 /*
@@ -4578,8 +4571,7 @@ rs_close(struct tty_struct *tty, struct 
 	shutdown(info);
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	tty_ldisc_flush(tty);
 	tty->closing = 0;
 	info->event = 0;
 	info->tty = 0;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/i386/kernel/microcode.c linux-2.4.29-pre3/arch/i386/kernel/microcode.c
--- linux-2.4.28/arch/i386/kernel/microcode.c	2004-04-14 13:05:25.000000000 +0000
+++ linux-2.4.29-pre3/arch/i386/kernel/microcode.c	2004-12-22 16:06:00.197267952 +0000
@@ -109,7 +109,10 @@ MODULE_LICENSE("GPL");
 #define get_datasize(mc) \
 	(((microcode_t *)mc)->hdr.datasize ? \
 	 ((microcode_t *)mc)->hdr.datasize : DEFAULT_UCODE_DATASIZE)
-#define sigmatch(s1, s2, p1, p2) (((s1) == (s2)) && ((p1) & (p2)))
+
+#define sigmatch(s1, s2, p1, p2) \
+	(((s1) == (s2)) && (((p1) & (p2)) || (((p1) == 0) && ((p2) == 0))))
+
 #define exttable_size(et) ((et)->count * EXT_SIGNATURE_SIZE + EXT_HEADER_SIZE)
 
 /* serialize access to the physical write to MSR 0x79 */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/i386/kernel/pci-irq.c linux-2.4.29-pre3/arch/i386/kernel/pci-irq.c
--- linux-2.4.28/arch/i386/kernel/pci-irq.c	2004-12-22 16:17:15.625587240 +0000
+++ linux-2.4.29-pre3/arch/i386/kernel/pci-irq.c	2004-12-22 16:07:52.544188624 +0000
@@ -248,6 +248,44 @@ static int pirq_opti_set(struct pci_dev 
 }
 
 /*
+ * OPTI Viper-M/N+: Bit field with 3 bits per entry.
+ * Due to the lack of a specification the information about this chipset
+ * was taken from the NetBSD source code.
+ */
+static int pirq_viper_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
+{
+	static const int viper_irq_decode[] = { 0, 5, 9, 10, 11, 12, 14, 15 };
+	u32 irq;
+
+	pci_read_config_dword(router, 0x40, &irq);
+	irq >>= (pirq-1)*3;
+	irq &= 7;
+
+	return viper_irq_decode[irq];
+}
+
+static int pirq_viper_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
+{
+	static const int viper_irq_map[] = { -1, -1, -1, -1, -1, 1, -1, -1, -1, 2, 3, 4, 5, -1, 6, 7 };
+	int newval = viper_irq_map[irq];
+	u32 val;
+	u32 mask = 7 << (3*(pirq-1));
+#if 0
+	mask |= 0x10000UL << (pirq-1);	/* edge triggered */
+#endif
+
+	if ( newval == -1 )
+		return 0;
+	
+	pci_read_config_dword(router, 0x40, &val);
+	val &= ~mask;
+	val |= newval << (3*(pirq-1));
+	pci_write_config_dword(router, 0x40, val);
+
+	return 1;
+}
+
+/*
  * Cyrix: nibble offset 0x5C
  */
 static int pirq_cyrix_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
@@ -715,9 +753,16 @@ static __init int opti_router_probe(stru
 			r->name = "OPTI";
 			r->get = pirq_opti_get;
 			r->set = pirq_opti_set;
-			return 1;
+			break;
+		case PCI_DEVICE_ID_OPTI_82C558:
+			r->name = "OPTI VIPER";
+			r->get = pirq_viper_get;
+			r->set = pirq_viper_set;
+			break;
+		default:
+			return 0;
 	}
-	return 0;
+	return 1;
 }
 
 static __init int ite_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/ia64/ia32/binfmt_elf32.c linux-2.4.29-pre3/arch/ia64/ia32/binfmt_elf32.c
--- linux-2.4.28/arch/ia64/ia32/binfmt_elf32.c	2004-08-07 23:26:04.000000000 +0000
+++ linux-2.4.29-pre3/arch/ia64/ia32/binfmt_elf32.c	2004-12-22 16:07:39.874114768 +0000
@@ -95,7 +95,11 @@ ia64_elf32_init (struct pt_regs *regs)
 		vma->vm_private_data = NULL;
 		down_write(&current->mm->mmap_sem);
 		{
-			insert_vm_struct(current->mm, vma);
+			if (insert_vm_struct(current->mm, vma)) {
+				kmem_cache_free(vm_area_cachep, vma);
+				up_write(&current->mm->mmap_sem);
+				return;
+			}
 		}
 		up_write(&current->mm->mmap_sem);
 	}
@@ -117,7 +121,11 @@ ia64_elf32_init (struct pt_regs *regs)
 		vma->vm_private_data = NULL;
 		down_write(&current->mm->mmap_sem);
 		{
-			insert_vm_struct(current->mm, vma);
+			if (insert_vm_struct(current->mm, vma)) {
+				kmem_cache_free(vm_area_cachep, vma);
+				up_write(&current->mm->mmap_sem);
+				return;
+			}
 		}
 		up_write(&current->mm->mmap_sem);
 	}
@@ -164,7 +172,7 @@ ia32_setup_arg_pages (struct linux_binpr
 {
 	unsigned long stack_base;
 	struct vm_area_struct *mpnt;
-	int i;
+	int i, ret;
 
 	stack_base = IA32_STACK_TOP - MAX_ARG_PAGES*PAGE_SIZE;
 
@@ -188,7 +196,11 @@ ia32_setup_arg_pages (struct linux_binpr
 		mpnt->vm_pgoff = 0;
 		mpnt->vm_file = NULL;
 		mpnt->vm_private_data = 0;
-		insert_vm_struct(current->mm, mpnt);
+		if ((ret = insert_vm_struct(current->mm, mpnt))) {
+			up_write(&current->mm->mmap_sem);
+			kmem_cache_free(vm_area_cachep, mpnt);
+			return ret;
+		}
 		current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
 	}
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/ia64/ia32/sys_ia32.c linux-2.4.29-pre3/arch/ia64/ia32/sys_ia32.c
--- linux-2.4.28/arch/ia64/ia32/sys_ia32.c	2004-08-07 23:26:04.000000000 +0000
+++ linux-2.4.29-pre3/arch/ia64/ia32/sys_ia32.c	2004-12-22 16:07:02.329822368 +0000
@@ -111,6 +111,8 @@ nargs (unsigned int arg, char **ap)
 			*ap++ = (char *) A(addr);
 		arg += sizeof(unsigned int);
 		n++;
+		if (n >= (MAX_ARG_PAGES * PAGE_SIZE) / sizeof(char *))
+			return -E2BIG;
 	} while (addr);
 	return n - 1;
 }
@@ -1367,6 +1369,11 @@ struct cmsghdr32 {
 #define __CMSG32_FIRSTHDR(ctl,len) \
 	((len) >= sizeof(struct cmsghdr32) ? (struct cmsghdr32 *)(ctl) : (struct cmsghdr32 *)NULL)
 #define CMSG32_FIRSTHDR(msg)	__CMSG32_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
+#define CMSG32_OK(ucmlen, ucmsg, mhdr) \
+	((ucmlen) >= sizeof(struct cmsghdr) && \
+	 (ucmlen) <= (unsigned long) \
+	 ((mhdr)->msg_controllen - \
+	  ((char *)(ucmsg) - (char *)(mhdr)->msg_control)))
 
 static inline struct cmsghdr32 *
 __cmsg32_nxthdr (void *ctl, __kernel_size_t size, struct cmsghdr32 *cmsg, int cmsg_len)
@@ -1427,10 +1434,7 @@ get_cmsghdr32 (struct msghdr *kmsg, unsi
 			return -EFAULT;
 
 		/* Catch bogons. */
-		if (CMSG32_ALIGN(ucmlen) < CMSG32_ALIGN(sizeof(struct cmsghdr32)))
-			return -EINVAL;
-		if ((unsigned long)(((char *)ucmsg - (char *)kmsg->msg_control) + ucmlen)
-		    > kmsg->msg_controllen)
+		if (!CMSG32_OK(ucmlen, ucmsg, kmsg))
 			return -EINVAL;
 
 		tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/ia64/mm/init.c linux-2.4.29-pre3/arch/ia64/mm/init.c
--- linux-2.4.28/arch/ia64/mm/init.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/ia64/mm/init.c	2004-12-22 16:06:31.634488768 +0000
@@ -105,7 +105,13 @@ ia64_init_addr_space (void)
 		vma->vm_pgoff = 0;
 		vma->vm_file = NULL;
 		vma->vm_private_data = NULL;
-		insert_vm_struct(current->mm, vma);
+		down_write(&current->mm->mmap_sem);
+		if (insert_vm_struct(current->mm, vma)) {
+			up_write(&current->mm->mmap_sem);
+			kmem_cache_free(vm_area_cachep, vma);
+			return;
+		}
+		up_write(&current->mm->mmap_sem);
 	}
 
 	/* map NaT-page at address zero to speed up speculative dereferencing of NULL: */
@@ -117,7 +123,13 @@ ia64_init_addr_space (void)
 			vma->vm_end = PAGE_SIZE;
 			vma->vm_page_prot = __pgprot(pgprot_val(PAGE_READONLY) | _PAGE_MA_NAT);
 			vma->vm_flags = VM_READ | VM_MAYREAD | VM_IO | VM_RESERVED;
-			insert_vm_struct(current->mm, vma);
+			down_write(&current->mm->mmap_sem);
+			if (insert_vm_struct(current->mm, vma)) {
+				up_write(&current->mm->mmap_sem);
+				kmem_cache_free(vm_area_cachep, vma);
+				return;
+			}
+			up_write(&current->mm->mmap_sem);
 		}
 	}
 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/m68k/kernel/setup.c linux-2.4.29-pre3/arch/m68k/kernel/setup.c
--- linux-2.4.28/arch/m68k/kernel/setup.c	2004-12-22 16:17:15.646584048 +0000
+++ linux-2.4.29-pre3/arch/m68k/kernel/setup.c	2004-12-22 16:07:41.624848616 +0000
@@ -597,7 +597,5 @@ void check_bugs(void)
 		printk( KERN_EMERG "(see http://no-fpu.linux-m68k.org)\n" );
 		panic( "no FPU" );
 	}
-
-#endif /* CONFIG_SUN3 */
-
+#endif /* !CONFIG_M68KFPU_EMU */
 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/Makefile linux-2.4.29-pre3/arch/mips/Makefile
--- linux-2.4.28/arch/mips/Makefile	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/Makefile	2004-12-22 16:05:32.002554200 +0000
@@ -5,7 +5,7 @@
 #
 # Copyright (C) 1994, 1995, 1996 by Ralf Baechle
 # DECStation modifications by Paul M. Antoine, 1996
-# Copyright (C) 2002, 2003  Maciej W. Rozycki
+# Copyright (C) 2002, 2003, 2004  Maciej W. Rozycki
 #
 # This file is included by the global makefile so that you can add your own
 # architecture-specific flags and dependencies. Remember to do have actions
@@ -28,6 +28,8 @@ ifdef CONFIG_CROSSCOMPILE
 CROSS_COMPILE	= $(tool-prefix)
 endif
 
+MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+
 check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi)
 
 #
@@ -44,7 +46,7 @@ check_gcc = $(shell if $(CC) $(1) -S -o 
 GCCFLAGS	:= -I $(TOPDIR)/include/asm/gcc
 GCCFLAGS	+= -G 0 -mno-abicalls -fno-pic -pipe
 GCCFLAGS	+= $(call check_gcc, -finline-limit=100000,)
-LINKFLAGS	+= -G 0 -static # -N
+LINKFLAGS	+= -G 0 -static -n
 MODFLAGS	+= -mlong-calls
 
 ifdef CONFIG_DEBUG_INFO
@@ -98,6 +100,11 @@ while :; do \
 	gas_abi=; gas_opt=; gas_cpu=; gas_isa=; \
 	break; \
 done; \
+if test "$$gcc_opt" = -march= && test -n "$$gcc_abi"; then \
+	$(CC) $$gcc_abi $$gcc_opt$$gcc_cpu -S -o /dev/null \
+		-xc /dev/null > /dev/null 2>&1 && \
+		gcc_isa=; \
+fi; \
 echo $$gcc_abi $$gcc_opt$$gcc_cpu $$gcc_isa $$gas_abi $$gas_opt$$gas_cpu $$gas_isa)
 
 #
@@ -168,7 +175,8 @@ endif
 
 AFLAGS		+= $(GCCFLAGS)
 CFLAGS		+= $(GCCFLAGS)
-LDFLAGS		+= -m $(ld-emul)
+
+LD		+= -m $(ld-emul)
 
 
 #
@@ -249,6 +257,13 @@ SUBDIRS       += arch/mips/au1000/db1x00
 LOADADDR      += 0x80100000
 endif
 
+ifdef CONFIG_MIPS_DB1550
+LIBS          += arch/mips/au1000/db1x00/db1x00.o \
+                 arch/mips/au1000/common/au1000.o
+SUBDIRS       += arch/mips/au1000/db1x00 arch/mips/au1000/common
+LOADADDR      += 0x80100000
+endif
+
 ifdef CONFIG_MIPS_DB1100
 LIBS          += arch/mips/au1000/db1x00/db1x00.o \
                  arch/mips/au1000/common/au1000.o
@@ -463,6 +478,18 @@ SUBDIRS		+= arch/mips/momentum/ocelot_c
 LOADADDR	:= 0x80100000
 endif
 
+ifdef CONFIG_PMC_BIG_SUR
+CORE_FILES	+= arch/mips/pmc-sierra/big_sur/big_sur.o
+SUBDIRS		+= arch/mips/pmc-sierra/big_sur
+LOADADDR	:= 0x80100000
+endif
+
+ifdef CONFIG_PMC_STRETCH
+CORE_FILES	+= arch/mips/pmc-sierra/stretch/stretch.o
+SUBDIRS		+= arch/mips/pmc-sierra/stretch
+LOADADDR	:= 0x80200000
+endif
+
 ifdef CONFIG_MOMENCO_JAGUAR_ATX
 LIBS		+= arch/mips/momentum/jaguar_atx/jaguar_atx.o
 SUBDIRS		+= arch/mips/momentum/jaguar_atx
@@ -723,7 +750,10 @@ rom.bin rom.sw: vmlinux
 	$(MAKE) -C arch/$(ARCH)/lasat/image $@
 endif
 
-MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+boot: mips-boot
+
+mips-boot: vmlinux
+	@$(MAKEBOOT) boot
 
 vmlinux.ecoff: vmlinux
 	@$(MAKEBOOT) $@
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/common/Makefile linux-2.4.29-pre3/arch/mips/au1000/common/Makefile
--- linux-2.4.28/arch/mips/au1000/common/Makefile	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/common/Makefile	2004-12-22 16:07:43.320590824 +0000
@@ -18,8 +18,10 @@ O_TARGET := au1000.o
 
 export-objs		= prom.o clocks.o power.o usbdev.o
 
-obj-y := prom.o int-handler.o dma.o irq.o puts.o time.o reset.o \
-	clocks.o power.o setup.o sleeper.o
+obj-y := prom.o int-handler.o irq.o puts.o time.o reset.o cputable.o \
+	au1xxx_irqmap.o clocks.o power.o setup.o sleeper.o dma.o dbdma.o
+  
+export-objs += dma.o dbdma.o
 
 obj-$(CONFIG_AU1X00_USB_DEVICE) += usbdev.o
 obj-$(CONFIG_KGDB) += dbg_io.o
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/common/au1xxx_irqmap.c linux-2.4.29-pre3/arch/mips/au1000/common/au1xxx_irqmap.c
--- linux-2.4.28/arch/mips/au1000/common/au1xxx_irqmap.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/common/au1xxx_irqmap.c	2004-12-22 16:05:56.004905288 +0000
@@ -0,0 +1,223 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Au1xxx processor specific IRQ tables
+ *
+ * Copyright 2004 Embedded Edge, LLC
+ *	dan@embeddededge.com
+ *
+ *  This program is free software; you can redistribute	 it and/or modify it
+ *  under  the terms of	 the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the	License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
+ *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
+ *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/delay.h>
+
+#include <asm/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/au1000.h>
+
+/* The IC0 interrupt table.  This is processor, rather than
+ * board dependent, so no reason to keep this info in the board
+ * dependent files.
+ *
+ * Careful if you change match 2 request!
+ * The interrupt handler is called directly from the low level dispatch code.
+ */
+au1xxx_irq_map_t au1xxx_ic0_map[] = {
+
+#if defined(CONFIG_SOC_AU1000)
+	{ AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_UART1_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_UART2_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
+	{ AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
+
+#elif defined(CONFIG_SOC_AU1500)
+
+	{ AU1500_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_PCI_INTA, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1000_PCI_INTB, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1500_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_PCI_INTC, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1000_PCI_INTD, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
+	{ AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1500_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1500_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
+
+#elif defined(CONFIG_SOC_AU1100)
+
+	{ AU1100_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1100_UART1_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1100_SD_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1100_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
+	{ AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1100_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
+	/*{ AU1000_GPIO215_208_INT, INTC_INT_HIGH_LEVEL, 0},*/
+	{ AU1100_LCD_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
+
+#elif defined(CONFIG_SOC_AU1550)
+
+	{ AU1550_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1550_PCI_INTA, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1550_PCI_INTB, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1550_DDMA_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1550_CRYPTO_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1550_PCI_INTC, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1550_PCI_INTD, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1550_PCI_RST_INT, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1550_UART1_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1550_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1550_PSC0_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1550_PSC1_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1550_PSC2_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1550_PSC3_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1550_TOY_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1550_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1550_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1550_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
+	{ AU1550_RTC_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1550_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1550_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1550_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1550_NAND_INT, INTC_INT_RISE_EDGE, 0},
+	{ AU1550_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1550_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1550_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1550_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1550_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
+
+#elif defined(CONFIG_SOC_AU1200)
+
+	{ AU1200_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1200_SWT_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1200_SD_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1200_DDMA_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1200_MAE_BE_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1200_UART1_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1200_MAE_FE_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1200_PSC0_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1200_PSC1_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1200_AES_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1200_CAMERA_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1200_TOY_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1200_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1200_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1200_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
+	{ AU1200_RTC_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1200_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1200_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1200_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
+	{ AU1200_NAND_INT, INTC_INT_RISE_EDGE, 0},
+	{ AU1200_USB_INT, INTC_INT_HIGH_LEVEL, 0 },
+	{ AU1200_LCD_INT, INTC_INT_HIGH_LEVEL, 0},
+	{ AU1200_MAE_BOTH_INT, INTC_INT_HIGH_LEVEL, 0},
+
+#else
+#error "Error: Unknown Alchemy SOC"
+#endif
+
+};
+
+int au1xxx_ic0_nr_irqs = sizeof(au1xxx_ic0_map)/sizeof(au1xxx_irq_map_t);
+
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/common/clocks.c linux-2.4.29-pre3/arch/mips/au1000/common/clocks.c
--- linux-2.4.28/arch/mips/au1000/common/clocks.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/common/clocks.c	2004-12-22 16:06:30.785617816 +0000
@@ -95,4 +95,5 @@ unsigned int get_au1x00_lcd_clock(void)
 	return lcd_clock;
 }
 
+EXPORT_SYMBOL(get_au1x00_speed);
 EXPORT_SYMBOL(get_au1x00_lcd_clock);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/common/cputable.c linux-2.4.29-pre3/arch/mips/au1000/common/cputable.c
--- linux-2.4.28/arch/mips/au1000/common/cputable.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/common/cputable.c	2004-12-22 16:07:09.865676744 +0000
@@ -0,0 +1,57 @@
+/*
+ *  arch/mips/au1000/common/cputable.c
+ *
+ *  Copyright (C) 2004 Dan Malek (dan@embeddededge.com)
+ *	Copied from PowerPC and updated for Alchemy Au1xxx processors.
+ *
+ *  Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org)
+ *
+ *  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/string.h>
+#include <linux/sched.h>
+#include <linux/threads.h>
+#include <linux/init.h>
+#include <asm/au1000.h>
+
+struct cpu_spec* cur_cpu_spec[NR_CPUS];
+
+/* With some thought, we can probably use the mask to reduce the
+ * size of the table.
+ */
+struct cpu_spec	cpu_specs[] = {
+    { 0xffffffff, 0x00030100, "Au1000 DA", 1, 0 },
+    { 0xffffffff, 0x00030201, "Au1000 HA", 1, 0 },
+    { 0xffffffff, 0x00030202, "Au1000 HB", 1, 0 },
+    { 0xffffffff, 0x00030203, "Au1000 HC", 1, 1 },
+    { 0xffffffff, 0x00030204, "Au1000 HD", 1, 1 },
+    { 0xffffffff, 0x01030200, "Au1500 AB", 1, 1 },
+    { 0xffffffff, 0x01030201, "Au1500 AC", 0, 1 },
+    { 0xffffffff, 0x01030202, "Au1500 AD", 0, 1 },
+    { 0xffffffff, 0x02030200, "Au1100 AB", 1, 1 },
+    { 0xffffffff, 0x02030201, "Au1100 BA", 1, 1 },
+    { 0xffffffff, 0x02030202, "Au1100 BC", 1, 1 },
+    { 0xffffffff, 0x02030203, "Au1100 BD", 0, 1 },
+    { 0xffffffff, 0x02030204, "Au1100 BE", 0, 1 },
+    { 0xffffffff, 0x03030200, "Au1550 AA", 0, 1 },
+    { 0xffffffff, 0x04030200, "Au1200 AA", 0, 1 },
+    { 0x00000000, 0x00000000, "Unknown Au1xxx", 1, 0 },
+};
+
+void
+set_cpuspec(void)
+{
+	struct	cpu_spec *sp;
+	u32	prid;
+
+	prid = read_c0_prid();
+	sp = cpu_specs;
+	while ((prid & sp->prid_mask) != sp->prid_value)
+		sp++;
+	cur_cpu_spec[0] = sp;
+}
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/common/dbdma.c linux-2.4.29-pre3/arch/mips/au1000/common/dbdma.c
--- linux-2.4.28/arch/mips/au1000/common/dbdma.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/common/dbdma.c	2004-12-22 16:07:37.138530640 +0000
@@ -0,0 +1,834 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *      The Descriptor Based DMA channel manager that first appeared
+ *	on the Au1550.  I started with dma.c, but I think all that is
+ *	left is this initial comment :-)
+ *
+ * Copyright 2004 Embedded Edge, LLC
+ *	dan@embeddededge.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <asm/au1000.h>
+#include <asm/au1xxx_dbdma.h>
+#include <asm/system.h>
+
+#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
+
+/*
+ * The Descriptor Based DMA supports up to 16 channels.
+ *
+ * There are 32 devices defined. We keep an internal structure
+ * of devices using these channels, along with additional
+ * information.
+ *
+ * We allocate the descriptors and allow access to them through various
+ * functions.  The drivers allocate the data buffers and assign them
+ * to the descriptors.
+ */
+static spinlock_t au1xxx_dbdma_spin_lock = SPIN_LOCK_UNLOCKED;
+
+/* I couldn't find a macro that did this......
+*/
+#define ALIGN_ADDR(x, a)	((((u32)(x)) + (a-1)) & ~(a-1))
+
+static volatile dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE;
+static int dbdma_initialized;
+static void au1xxx_dbdma_init(void);
+
+typedef struct dbdma_device_table {
+	u32		dev_id;
+	u32		dev_flags;
+	u32		dev_tsize;
+	u32		dev_devwidth;
+	u32		dev_physaddr;		/* If FIFO */
+	u32		dev_intlevel;
+	u32		dev_intpolarity;
+} dbdev_tab_t;
+
+typedef struct dbdma_chan_config {
+	u32			chan_flags;
+	u32			chan_index;
+	dbdev_tab_t		*chan_src;
+	dbdev_tab_t		*chan_dest;
+	au1x_dma_chan_t		*chan_ptr;
+	au1x_ddma_desc_t	*chan_desc_base;
+	au1x_ddma_desc_t	*get_ptr, *put_ptr, *cur_ptr;
+	void			*chan_callparam;
+	void (*chan_callback)(int, void *, struct pt_regs *);
+} chan_tab_t;
+
+#define	DEV_FLAGS_INUSE		(1 << 0)
+#define	DEV_FLAGS_ANYUSE	(1 << 1)
+#define DEV_FLAGS_OUT		(1 << 2)
+#define DEV_FLAGS_IN		(1 << 3)
+
+static dbdev_tab_t dbdev_tab[] = {
+#ifdef CONFIG_SOC_AU1550
+	/* UARTS */
+	{ DSCR_CMD0_UART0_TX, DEV_FLAGS_OUT, 0, 8, 0x11100004, 0, 0 },
+	{ DSCR_CMD0_UART0_RX, DEV_FLAGS_IN, 0, 8, 0x11100000, 0, 0 },
+	{ DSCR_CMD0_UART3_TX, DEV_FLAGS_OUT, 0, 8, 0x11400004, 0, 0 },
+	{ DSCR_CMD0_UART3_RX, DEV_FLAGS_IN, 0, 8, 0x11400000, 0, 0 },
+
+	/* EXT DMA */
+	{ DSCR_CMD0_DMA_REQ0, 0, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_DMA_REQ1, 0, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_DMA_REQ2, 0, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_DMA_REQ3, 0, 0, 0, 0x00000000, 0, 0 },
+
+	/* USB DEV */
+	{ DSCR_CMD0_USBDEV_RX0, DEV_FLAGS_IN, 4, 8, 0x10200000, 0, 0 },
+	{ DSCR_CMD0_USBDEV_TX0, DEV_FLAGS_OUT, 4, 8, 0x10200004, 0, 0 },
+	{ DSCR_CMD0_USBDEV_TX1, DEV_FLAGS_OUT, 4, 8, 0x10200008, 0, 0 },
+	{ DSCR_CMD0_USBDEV_TX2, DEV_FLAGS_OUT, 4, 8, 0x1020000c, 0, 0 },
+	{ DSCR_CMD0_USBDEV_RX3, DEV_FLAGS_IN, 4, 8, 0x10200010, 0, 0 },
+	{ DSCR_CMD0_USBDEV_RX4, DEV_FLAGS_IN, 4, 8, 0x10200014, 0, 0 },
+
+	/* PSC 0 */
+	{ DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 0, 0x11a0001c, 0, 0 },
+	{ DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 0, 0x11a0001c, 0, 0 },
+
+	/* PSC 1 */
+	{ DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 0, 0x11b0001c, 0, 0 },
+	{ DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 0, 0x11b0001c, 0, 0 },
+
+	/* PSC 2 */
+	{ DSCR_CMD0_PSC2_TX, DEV_FLAGS_OUT, 0, 0, 0x10a0001c, 0, 0 },
+	{ DSCR_CMD0_PSC2_RX, DEV_FLAGS_IN, 0, 0, 0x10a0001c, 0, 0 },
+
+	/* PSC 3 */
+	{ DSCR_CMD0_PSC3_TX, DEV_FLAGS_OUT, 0, 0, 0x10b0001c, 0, 0 },
+	{ DSCR_CMD0_PSC3_RX, DEV_FLAGS_IN, 0, 0, 0x10b0001c, 0, 0 },
+
+	{ DSCR_CMD0_PCI_WRITE, 0, 0, 0, 0x00000000, 0, 0 },	/* PCI */
+	{ DSCR_CMD0_NAND_FLASH, 0, 0, 0, 0x00000000, 0, 0 },	/* NAND */
+
+	/* MAC 0 */
+	{ DSCR_CMD0_MAC0_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_MAC0_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
+
+	/* MAC 1 */
+	{ DSCR_CMD0_MAC1_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_MAC1_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
+
+#endif /* CONFIG_SOC_AU1550 */
+
+#ifdef CONFIG_SOC_AU1200
+	{ DSCR_CMD0_UART0_TX, DEV_FLAGS_OUT, 0, 8, 0x11100004, 0, 0 },
+	{ DSCR_CMD0_UART0_RX, DEV_FLAGS_IN, 0, 8, 0x11100000, 0, 0 },
+	{ DSCR_CMD0_UART1_TX, DEV_FLAGS_OUT, 0, 8, 0x11200004, 0, 0 },
+	{ DSCR_CMD0_UART1_RX, DEV_FLAGS_IN, 0, 8, 0x11200000, 0, 0 },
+
+	{ DSCR_CMD0_DMA_REQ0, 0, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_DMA_REQ1, 0, 0, 0, 0x00000000, 0, 0 },
+
+	{ DSCR_CMD0_MAE_BE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_MAE_FE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_MAE_BOTH, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_LCD, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+
+	{ DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_SDMS_TX1, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_SDMS_RX1, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+
+	{ DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_AES_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+
+	{ DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 0, 0x11a0001c, 0, 0 },
+	{ DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 0, 0x11a0001c, 0, 0 },
+	{ DSCR_CMD0_PSC0_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+
+	{ DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 0, 0x11b0001c, 0, 0 },
+	{ DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 0, 0x11b0001c, 0, 0 },
+	{ DSCR_CMD0_PSC1_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+
+	{ DSCR_CMD0_CIM_RXA, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_CIM_RXB, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_CIM_RXC, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_CIM_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+
+	{ DSCR_CMD0_NAND_FLASH, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+
+#endif // CONFIG_SOC_AU1200
+
+	{ DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+	{ DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+};
+
+#define DBDEV_TAB_SIZE (sizeof(dbdev_tab) / sizeof(dbdev_tab_t))
+
+static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS];
+
+static dbdev_tab_t *
+find_dbdev_id (u32 id)
+{
+	int i;
+	dbdev_tab_t *p;
+	for (i = 0; i < DBDEV_TAB_SIZE; ++i) {
+		p = &dbdev_tab[i];
+		if (p->dev_id == id)
+			return p;
+	}
+	return NULL;
+}
+
+/* Allocate a channel and return a non-zero descriptor if successful.
+*/
+u32
+au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
+       void (*callback)(int, void *, struct pt_regs *), void *callparam)
+{
+	unsigned long   flags;
+	u32		used, chan, rv;
+	u32		dcp;
+	int		i;
+	dbdev_tab_t	*stp, *dtp;
+	chan_tab_t	*ctp;
+	volatile au1x_dma_chan_t *cp;
+
+	/* We do the intialization on the first channel allocation.
+	 * We have to wait because of the interrupt handler initialization
+	 * which can't be done successfully during board set up.
+	 */
+	if (!dbdma_initialized)
+		au1xxx_dbdma_init();
+	dbdma_initialized = 1;
+
+	if ((srcid > DSCR_NDEV_IDS) || (destid > DSCR_NDEV_IDS))
+		return 0;
+	
+	if ((stp = find_dbdev_id(srcid)) == NULL) return 0;
+	if ((dtp = find_dbdev_id(destid)) == NULL) return 0;
+
+	used = 0;
+	rv = 0;
+
+	/* Check to see if we can get both channels.
+	*/
+	spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags);
+	if (!(stp->dev_flags & DEV_FLAGS_INUSE) ||
+	     (stp->dev_flags & DEV_FLAGS_ANYUSE)) {
+	     	/* Got source */
+		stp->dev_flags |= DEV_FLAGS_INUSE;
+		if (!(dtp->dev_flags & DEV_FLAGS_INUSE) ||
+		     (dtp->dev_flags & DEV_FLAGS_ANYUSE)) {
+			/* Got destination */
+			dtp->dev_flags |= DEV_FLAGS_INUSE;
+		}
+		else {
+			/* Can't get dest.  Release src.
+			*/
+			stp->dev_flags &= ~DEV_FLAGS_INUSE;
+			used++;
+		}
+	}
+	else {
+		used++;
+	}
+	spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags);
+
+	if (!used) {
+		/* Let's see if we can allocate a channel for it.
+		*/
+		ctp = NULL;
+		chan = 0;
+		spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags);
+		for (i=0; i<NUM_DBDMA_CHANS; i++) {
+			if (chan_tab_ptr[i] == NULL) {
+				/* If kmalloc fails, it is caught below same
+				 * as a channel not available.
+				 */
+				ctp = (chan_tab_t *)kmalloc(sizeof(chan_tab_t), GFP_KERNEL);
+				chan_tab_ptr[i] = ctp;
+				ctp->chan_index = chan = i;
+				break;
+			}
+		}
+		spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags);
+
+		if (ctp != NULL) {
+			memset(ctp, 0, sizeof(chan_tab_t));
+			dcp = DDMA_CHANNEL_BASE;
+			dcp += (0x0100 * chan);
+			ctp->chan_ptr = (au1x_dma_chan_t *)dcp;
+			cp = (volatile au1x_dma_chan_t *)dcp;
+			ctp->chan_src = stp;
+			ctp->chan_dest = dtp;
+			ctp->chan_callback = callback;
+			ctp->chan_callparam = callparam;
+
+			/* Initialize channel configuration.
+			*/
+			i = 0;
+			if (stp->dev_intlevel)
+				i |= DDMA_CFG_SED;
+			if (stp->dev_intpolarity)
+				i |= DDMA_CFG_SP;
+			if (dtp->dev_intlevel)
+				i |= DDMA_CFG_DED;
+			if (dtp->dev_intpolarity)
+				i |= DDMA_CFG_DP;
+			cp->ddma_cfg = i;
+			au_sync();
+
+			/* Return a non-zero value that can be used to
+			 * find the channel information in subsequent
+			 * operations.
+			 */
+			rv = (u32)(&chan_tab_ptr[chan]);
+		}
+		else {
+			/* Release devices.
+			*/
+			stp->dev_flags &= ~DEV_FLAGS_INUSE;
+			dtp->dev_flags &= ~DEV_FLAGS_INUSE;
+		}
+	}
+	return rv;
+}
+
+/* Set the device width if source or destination is a FIFO.
+ * Should be 8, 16, or 32 bits.
+ */
+u32
+au1xxx_dbdma_set_devwidth(u32 chanid, int bits)
+{
+	u32		rv;
+	chan_tab_t	*ctp;
+	dbdev_tab_t	*stp, *dtp;
+
+	ctp = *((chan_tab_t **)chanid);
+	stp = ctp->chan_src;
+	dtp = ctp->chan_dest;
+	rv = 0;
+
+	if (stp->dev_flags & DEV_FLAGS_IN) {	/* Source in fifo */
+		rv = stp->dev_devwidth;
+		stp->dev_devwidth = bits;
+	}
+	if (dtp->dev_flags & DEV_FLAGS_OUT) {	/* Destination out fifo */
+		rv = dtp->dev_devwidth;
+		dtp->dev_devwidth = bits;
+	}
+
+	return rv;
+}
+
+/* Allocate a descriptor ring, initializing as much as possible.
+*/
+u32
+au1xxx_dbdma_ring_alloc(u32 chanid, int entries)
+{
+	int			i;
+	u32			desc_base, srcid, destid;
+	u32			cmd0, cmd1, src1, dest1;
+	u32			src0, dest0;
+	chan_tab_t		*ctp;
+	dbdev_tab_t		*stp, *dtp;
+	au1x_ddma_desc_t	*dp;
+
+	/* I guess we could check this to be within the
+	 * range of the table......
+	 */
+	ctp = *((chan_tab_t **)chanid);
+	stp = ctp->chan_src;
+	dtp = ctp->chan_dest;
+
+	/* The descriptors must be 32-byte aligned.  There is a
+	 * possibility the allocation will give us such an address,
+	 * and if we try that first we are likely to not waste larger
+	 * slabs of memory.
+	 */
+	desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t), GFP_KERNEL);
+	if (desc_base == 0)
+		return 0;
+	
+	if (desc_base & 0x1f) {
+		/* Lost....do it again, allocate extra, and round
+		 * the address base.
+		 */
+		kfree((const void *)desc_base);
+		i = entries * sizeof(au1x_ddma_desc_t);
+		i += (sizeof(au1x_ddma_desc_t) - 1);
+		if ((desc_base = (u32)kmalloc(i, GFP_KERNEL)) == 0)
+			return 0;
+
+		desc_base = ALIGN_ADDR(desc_base, sizeof(au1x_ddma_desc_t));
+	}
+	dp = (au1x_ddma_desc_t *)desc_base;
+
+	/* Keep track of the base descriptor.
+	*/
+	ctp->chan_desc_base = dp;
+
+	/* Initialize the rings with as much information as we know.
+	 */
+	srcid = stp->dev_id;
+	destid = dtp->dev_id;
+
+	cmd0 = cmd1 = src1 = dest1 = 0;
+	src0 = dest0 = 0;
+
+	cmd0 |= DSCR_CMD0_SID(srcid);
+	cmd0 |= DSCR_CMD0_DID(destid);
+	cmd0 |= DSCR_CMD0_IE | DSCR_CMD0_CV;
+	cmd0 |= DSCR_CMD0_ST(DSCR_CMD0_ST_CURRENT);
+
+	switch (stp->dev_devwidth) {
+	case 8:
+		cmd0 |= DSCR_CMD0_SW(DSCR_CMD0_BYTE);
+		break;
+	case 16:
+		cmd0 |= DSCR_CMD0_SW(DSCR_CMD0_HALFWORD);
+		break;
+	case 32:
+	default:
+		cmd0 |= DSCR_CMD0_SW(DSCR_CMD0_WORD);
+		break;
+	}
+
+	switch (dtp->dev_devwidth) {
+	case 8:
+		cmd0 |= DSCR_CMD0_DW(DSCR_CMD0_BYTE);
+		break;
+	case 16:
+		cmd0 |= DSCR_CMD0_DW(DSCR_CMD0_HALFWORD);
+		break;
+	case 32:
+	default:
+		cmd0 |= DSCR_CMD0_DW(DSCR_CMD0_WORD);
+		break;
+	}
+
+	/* If the device is marked as an in/out FIFO, ensure it is
+	 * set non-coherent.
+	 */
+	if (stp->dev_flags & DEV_FLAGS_IN)
+		cmd0 |= DSCR_CMD0_SN;		/* Source in fifo */
+	if (dtp->dev_flags & DEV_FLAGS_OUT)
+		cmd0 |= DSCR_CMD0_DN;		/* Destination out fifo */
+
+	/* Set up source1.  For now, assume no stride and increment.
+	 * A channel attribute update can change this later.
+	 */
+	switch (stp->dev_tsize) {
+	case 1:
+		src1 |= DSCR_SRC1_STS(DSCR_xTS_SIZE1);
+		break;
+	case 2:
+		src1 |= DSCR_SRC1_STS(DSCR_xTS_SIZE2);
+		break;
+	case 4:
+		src1 |= DSCR_SRC1_STS(DSCR_xTS_SIZE4);
+		break;
+	case 8:
+	default:
+		src1 |= DSCR_SRC1_STS(DSCR_xTS_SIZE8);
+		break;
+	}
+
+	/* If source input is fifo, set static address.
+	*/
+	if (stp->dev_flags & DEV_FLAGS_IN) {
+		src0 = stp->dev_physaddr;
+		src1 |= DSCR_SRC1_SAM(DSCR_xAM_STATIC);
+	}
+
+	/* Set up dest1.  For now, assume no stride and increment.
+	 * A channel attribute update can change this later.
+	 */
+	switch (dtp->dev_tsize) {
+	case 1:
+		dest1 |= DSCR_DEST1_DTS(DSCR_xTS_SIZE1);
+		break;
+	case 2:
+		dest1 |= DSCR_DEST1_DTS(DSCR_xTS_SIZE2);
+		break;
+	case 4:
+		dest1 |= DSCR_DEST1_DTS(DSCR_xTS_SIZE4);
+		break;
+	case 8:
+	default:
+		dest1 |= DSCR_DEST1_DTS(DSCR_xTS_SIZE8);
+		break;
+	}
+
+	/* If destination output is fifo, set static address.
+	*/
+	if (dtp->dev_flags & DEV_FLAGS_OUT) {
+		dest0 = dtp->dev_physaddr;
+		dest1 |= DSCR_DEST1_DAM(DSCR_xAM_STATIC);
+	}
+	
+	for (i=0; i<entries; i++) {
+		dp->dscr_cmd0 = cmd0;
+		dp->dscr_cmd1 = cmd1;
+		dp->dscr_source0 = src0;
+		dp->dscr_source1 = src1;
+		dp->dscr_dest0 = dest0;
+		dp->dscr_dest1 = dest1;
+		dp->dscr_stat = 0;
+		dp->dscr_nxtptr = DSCR_NXTPTR(virt_to_phys(dp + 1));
+		dp++;
+	}
+	
+	/* Make last descrptor point to the first.
+	*/
+	dp--;
+	dp->dscr_nxtptr = DSCR_NXTPTR(virt_to_phys(ctp->chan_desc_base));
+	ctp->get_ptr = ctp->put_ptr = ctp->cur_ptr = ctp->chan_desc_base;
+
+	return (u32)(ctp->chan_desc_base);
+}
+
+/* Put a source buffer into the DMA ring.
+ * This updates the source pointer and byte count.  Normally used
+ * for memory to fifo transfers.
+ */
+u32
+au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes)
+{
+	chan_tab_t		*ctp;
+	au1x_ddma_desc_t	*dp;
+
+	/* I guess we could check this to be within the
+	 * range of the table......
+	 */
+	ctp = *((chan_tab_t **)chanid);
+
+	/* We should have multiple callers for a particular channel,
+	 * an interrupt doesn't affect this pointer nor the descriptor,
+	 * so no locking should be needed.
+	 */
+	dp = ctp->put_ptr;
+
+	/* If the descriptor is valid, we are way ahead of the DMA
+	 * engine, so just return an error condition.
+	 */
+	if (dp->dscr_cmd0 & DSCR_CMD0_V) {
+		return 0;
+	}
+	
+	/* Load up buffer address and byte count.
+	*/
+	dp->dscr_source0 = virt_to_phys(buf);
+	dp->dscr_cmd1 = nbytes;
+	dp->dscr_cmd0 |= DSCR_CMD0_V;	/* Let it rip */
+	ctp->chan_ptr->ddma_dbell = 0xffffffff;	/* Make it go */
+	
+	/* Get next descriptor pointer.
+	*/
+	ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+
+	/* return something not zero.
+	*/
+	return nbytes;
+}
+
+/* Put a destination buffer into the DMA ring.
+ * This updates the destination pointer and byte count.  Normally used
+ * to place an empty buffer into the ring for fifo to memory transfers.
+ */
+u32
+au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes)
+{
+	chan_tab_t		*ctp;
+	au1x_ddma_desc_t	*dp;
+
+	/* I guess we could check this to be within the
+	 * range of the table......
+	 */
+	ctp = *((chan_tab_t **)chanid);
+
+	/* We should have multiple callers for a particular channel,
+	 * an interrupt doesn't affect this pointer nor the descriptor,
+	 * so no locking should be needed.
+	 */
+	dp = ctp->put_ptr;
+
+	/* If the descriptor is valid, we are way ahead of the DMA
+	 * engine, so just return an error condition.
+	 */
+	if (dp->dscr_cmd0 & DSCR_CMD0_V)
+		return 0;
+	
+	/* Load up buffer address and byte count.
+	*/
+	dp->dscr_dest0 = virt_to_phys(buf);
+	dp->dscr_cmd1 = nbytes;
+	dp->dscr_cmd0 |= DSCR_CMD0_V;	/* Let it rip */
+	
+	/* Get next descriptor pointer.
+	*/
+	ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+
+	/* return something not zero.
+	*/
+	return nbytes;
+}
+
+/* Get a destination buffer into the DMA ring.
+ * Normally used to get a full buffer from the ring during fifo
+ * to memory transfers.  This does not set the valid bit, you will
+ * have to put another destination buffer to keep the DMA going.
+ */
+u32
+au1xxx_dbdma_get_dest(u32 chanid, void **buf, int *nbytes)
+{
+	chan_tab_t		*ctp;
+	au1x_ddma_desc_t	*dp;
+	u32			rv;
+
+	/* I guess we could check this to be within the
+	 * range of the table......
+	 */
+	ctp = *((chan_tab_t **)chanid);
+
+	/* We should have multiple callers for a particular channel,
+	 * an interrupt doesn't affect this pointer nor the descriptor,
+	 * so no locking should be needed.
+	 */
+	dp = ctp->get_ptr;
+
+	/* If the descriptor is valid, we are way ahead of the DMA
+	 * engine, so just return an error condition.
+	 */
+	if (dp->dscr_cmd0 & DSCR_CMD0_V)
+		return 0;
+	
+	/* Return buffer address and byte count.
+	*/
+	*buf = (void *)(phys_to_virt(dp->dscr_dest0));
+	*nbytes = dp->dscr_cmd1;
+	rv = dp->dscr_stat;
+	
+	/* Get next descriptor pointer.
+	*/
+	ctp->get_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+
+	/* return something not zero.
+	*/
+	return rv;
+}
+
+void
+au1xxx_dbdma_stop(u32 chanid)
+{
+	chan_tab_t	*ctp;
+	volatile au1x_dma_chan_t *cp;
+	int halt_timeout = 0;
+
+	ctp = *((chan_tab_t **)chanid);
+
+	cp = ctp->chan_ptr;
+	cp->ddma_cfg &= ~DDMA_CFG_EN;	/* Disable channel */
+	au_sync();
+	while (!(cp->ddma_stat & DDMA_STAT_H)) {
+		udelay(1);
+		halt_timeout++;
+		if (halt_timeout > 100) {
+			printk("warning: DMA channel won't halt\n");
+			break;
+		}
+	}
+	/* clear current desc valid and doorbell */
+	cp->ddma_stat |= (DDMA_STAT_DB | DDMA_STAT_V);
+	au_sync();
+}
+
+/* Start using the current descriptor pointer.  If the dbdma encounters
+ * a not valid descriptor, it will stop.  In this case, we can just
+ * continue by adding a buffer to the list and starting again.
+ */
+void
+au1xxx_dbdma_start(u32 chanid)
+{
+	chan_tab_t	*ctp;
+	volatile au1x_dma_chan_t *cp;
+
+	ctp = *((chan_tab_t **)chanid);
+
+	cp = ctp->chan_ptr;
+	cp->ddma_desptr = virt_to_phys(ctp->cur_ptr);
+	cp->ddma_cfg |= DDMA_CFG_EN;	/* Enable channel */
+	au_sync();
+	cp->ddma_dbell = 0xffffffff;	/* Make it go */
+	au_sync();
+}
+
+void
+au1xxx_dbdma_reset(u32 chanid)
+{
+	chan_tab_t		*ctp;
+	au1x_ddma_desc_t	*dp;
+
+	au1xxx_dbdma_stop(chanid);
+
+	ctp = *((chan_tab_t **)chanid);
+	ctp->get_ptr = ctp->put_ptr = ctp->cur_ptr = ctp->chan_desc_base;
+
+	/* Run through the descriptors and reset the valid indicator.
+	*/
+	dp = ctp->chan_desc_base;
+
+	do {
+		dp->dscr_cmd0 &= ~DSCR_CMD0_V;
+		dp = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+	} while (dp != ctp->chan_desc_base);
+}
+
+u32
+au1xxx_get_dma_residue(u32 chanid)
+{
+	chan_tab_t	*ctp;
+	volatile au1x_dma_chan_t *cp;
+	u32		rv;
+
+	ctp = *((chan_tab_t **)chanid);
+	cp = ctp->chan_ptr;
+
+	/* This is only valid if the channel is stopped.
+	*/
+	rv = cp->ddma_bytecnt;
+	au_sync();
+
+	return rv;
+}
+
+void
+au1xxx_dbdma_chan_free(u32 chanid)
+{
+	chan_tab_t	*ctp;
+	dbdev_tab_t	*stp, *dtp;
+
+	ctp = *((chan_tab_t **)chanid);
+	stp = ctp->chan_src;
+	dtp = ctp->chan_dest;
+
+	au1xxx_dbdma_stop(chanid);
+
+	if (ctp->chan_desc_base != NULL)
+		kfree(ctp->chan_desc_base);
+	
+	stp->dev_flags &= ~DEV_FLAGS_INUSE;
+	dtp->dev_flags &= ~DEV_FLAGS_INUSE;
+	chan_tab_ptr[ctp->chan_index] = NULL;
+
+	kfree(ctp);
+}
+
+static void
+dbdma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	u32	intstat;
+	u32	chan_index;
+	chan_tab_t		*ctp;
+	au1x_ddma_desc_t	*dp;
+	volatile au1x_dma_chan_t *cp;
+
+	intstat = dbdma_gptr->ddma_intstat;
+	au_sync();
+	chan_index = au_ffs(intstat) - 1;
+
+	ctp = chan_tab_ptr[chan_index];
+	cp = ctp->chan_ptr;
+	dp = ctp->cur_ptr;
+
+	/* Reset interrupt.
+	*/
+	cp->ddma_irq = 0;
+	au_sync();
+
+	if (ctp->chan_callback)
+		(ctp->chan_callback)(irq, ctp->chan_callparam, regs);
+
+	ctp->cur_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+	
+}
+
+static void
+au1xxx_dbdma_init(void)
+{
+	dbdma_gptr->ddma_config = 0;
+	dbdma_gptr->ddma_throttle = 0;
+	dbdma_gptr->ddma_inten = 0xffff;
+	au_sync();
+
+	if (request_irq(AU1550_DDMA_INT, dbdma_interrupt, SA_INTERRUPT,
+			"Au1xxx dbdma", (void *)dbdma_gptr))
+		printk("Can't get 1550 dbdma irq");
+}
+
+void
+au1xxx_dbdma_dump(u32 chanid)
+{
+	chan_tab_t		*ctp;
+	au1x_ddma_desc_t	*dp;
+	dbdev_tab_t		*stp, *dtp;
+	volatile au1x_dma_chan_t *cp;
+
+	ctp = *((chan_tab_t **)chanid);
+	stp = ctp->chan_src;
+	dtp = ctp->chan_dest;
+	cp = ctp->chan_ptr;
+
+	printk("Chan %x, stp %x (dev %d)  dtp %x (dev %d) \n",
+		(u32)ctp, (u32)stp, stp - dbdev_tab, (u32)dtp, dtp - dbdev_tab);
+	printk("desc base %x, get %x, put %x, cur %x\n",
+		(u32)(ctp->chan_desc_base), (u32)(ctp->get_ptr),
+		(u32)(ctp->put_ptr), (u32)(ctp->cur_ptr));
+	
+	printk("dbdma chan %x\n", (u32)cp);
+	printk("cfg %08x, desptr %08x, statptr %08x\n",
+		cp->ddma_cfg, cp->ddma_desptr, cp->ddma_statptr);
+	printk("dbell %08x, irq %08x, stat %08x, bytecnt %08x\n",
+		cp->ddma_dbell, cp->ddma_irq, cp->ddma_stat, cp->ddma_bytecnt);
+
+
+	/* Run through the descriptors
+	*/
+	dp = ctp->chan_desc_base;
+
+	do {
+		printk("dp %08x, cmd0 %08x, cmd1 %08x\n",
+			(u32)dp, dp->dscr_cmd0, dp->dscr_cmd1);
+		printk("src0 %08x, src1 %08x, dest0 %08x\n",
+			dp->dscr_source0, dp->dscr_source1, dp->dscr_dest0);
+		printk("dest1 %08x, stat %08x, nxtptr %08x\n",
+			dp->dscr_dest1, dp->dscr_stat, dp->dscr_nxtptr);
+		dp = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
+	} while (dp != ctp->chan_desc_base);
+}
+
+#endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */
+
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/common/dma.c linux-2.4.29-pre3/arch/mips/au1000/common/dma.c
--- linux-2.4.28/arch/mips/au1000/common/dma.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/common/dma.c	2004-12-22 16:05:31.877573200 +0000
@@ -40,6 +40,8 @@
 #include <asm/au1000_dma.h>
 #include <asm/system.h>
 
+#include <linux/module.h>
+
 #if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1100)
 
 /*
@@ -73,7 +75,7 @@ struct dma_chan au1000_dma_table[NUM_AU1
 };
 
 // Device FIFO addresses and default DMA modes
-static const struct {
+static const struct dma_dev {
 	unsigned int fifo_addr;
 	unsigned int dma_mode;
 } dma_dev_table[DMA_NUM_DEV] = {
@@ -120,12 +122,19 @@ int au1000_dma_read_proc(char *buf, char
 	return len;
 }
 
+// Device FIFO addresses and default DMA modes - 2nd bank
+static const struct dma_dev dma_dev_table_bank2[DMA_NUM_DEV_BANK2] = {
+	{SD0_XMIT_FIFO, DMA_DS | DMA_DW8},		// coherent
+	{SD0_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8},	// coherent
+	{SD1_XMIT_FIFO, DMA_DS | DMA_DW8},		// coherent
+	{SD1_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8}	// coherent
+};
 
 void dump_au1000_dma_channel(unsigned int dmanr)
 {
 	struct dma_chan *chan;
 
-	if (dmanr > NUM_AU1000_DMA_CHANNELS)
+	if (dmanr >= NUM_AU1000_DMA_CHANNELS)
 		return;
 	chan = &au1000_dma_table[dmanr];
 
@@ -156,10 +165,16 @@ int request_au1000_dma(int dev_id, const
 		       void *irq_dev_id)
 {
 	struct dma_chan *chan;
+	const struct dma_dev *dev;
 	int i, ret;
 
-	if (dev_id < 0 || dev_id >= DMA_NUM_DEV)
+#if defined(CONFIG_SOC_AU1100)
+	if (dev_id < 0 || dev_id >= (DMA_NUM_DEV + DMA_NUM_DEV_BANK2))
 		return -EINVAL;
+#else
+ 	if (dev_id < 0 || dev_id >= DMA_NUM_DEV)
+ 		return -EINVAL;
+#endif
 
 	for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) {
 		if (au1000_dma_table[i].dev_id < 0)
@@ -170,6 +185,13 @@ int request_au1000_dma(int dev_id, const
 
 	chan = &au1000_dma_table[i];
 
+	if (dev_id >= DMA_NUM_DEV) {
+		dev_id -= DMA_NUM_DEV;
+		dev = &dma_dev_table_bank2[dev_id];
+	} else {
+		dev = &dma_dev_table[dev_id];
+	}
+
 	if (irqhandler) {
 		chan->irq = AU1000_DMA_INT_BASE + i;
 		chan->irq_dev = irq_dev_id;
@@ -188,8 +210,8 @@ int request_au1000_dma(int dev_id, const
 	chan->io = DMA_CHANNEL_BASE + i * DMA_CHANNEL_LEN;
 	chan->dev_id = dev_id;
 	chan->dev_str = dev_str;
-	chan->fifo_addr = dma_dev_table[dev_id].fifo_addr;
-	chan->mode = dma_dev_table[dev_id].dma_mode;
+	chan->fifo_addr = dev->fifo_addr;
+	chan->mode = dev->dma_mode;
 
 	/* initialize the channel before returning */
 	init_dma(i);
@@ -213,4 +235,9 @@ void free_au1000_dma(unsigned int dmanr)
 	chan->irq_dev = NULL;
 	chan->dev_id = -1;
 }
+
+EXPORT_SYMBOL(free_au1000_dma);
+EXPORT_SYMBOL(au1000_dma_table);
+EXPORT_SYMBOL(request_au1000_dma);
+
 #endif // AU1000 AU1500 AU1100
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/common/irq.c linux-2.4.29-pre3/arch/mips/au1000/common/irq.c
--- linux-2.4.28/arch/mips/au1000/common/irq.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/common/irq.c	2004-12-22 16:06:24.893513552 +0000
@@ -94,107 +94,6 @@ extern void counter0_irq(int irq, void *
 
 static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED;
 
-static void setup_local_irq(unsigned int irq_nr, int type, int int_req)
-{
-	if (irq_nr > AU1000_MAX_INTR) return;
-	/* Config2[n], Config1[n], Config0[n] */
-	if (irq_nr > AU1000_LAST_INTC0_INT) {
-		switch (type) {
-			case INTC_INT_RISE_EDGE: /* 0:0:1 */
-				au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
-				au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
-				au_writel(1<<(irq_nr-32), IC1_CFG0SET);
-				break;
-			case INTC_INT_FALL_EDGE: /* 0:1:0 */
-				au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
-				au_writel(1<<(irq_nr-32), IC1_CFG1SET);
-				au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
-				break;
-			case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */
-				au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
-				au_writel(1<<(irq_nr-32), IC1_CFG1SET);
-				au_writel(1<<(irq_nr-32), IC1_CFG0SET);
-				break;
-			case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
-				au_writel(1<<(irq_nr-32), IC1_CFG2SET);
-				au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
-				au_writel(1<<(irq_nr-32), IC1_CFG0SET);
-				break;
-			case INTC_INT_LOW_LEVEL: /* 1:1:0 */
-				au_writel(1<<(irq_nr-32), IC1_CFG2SET);
-				au_writel(1<<(irq_nr-32), IC1_CFG1SET);
-				au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
-				break;
-			case INTC_INT_DISABLED: /* 0:0:0 */
-				au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
-				au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
-				au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
-				break;
-			default: /* disable the interrupt */
-				printk("unexpected int type %d (irq %d)\n", type, irq_nr);
-				au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
-				au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
-				au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
-				return;
-		}
-		if (int_req) /* assign to interrupt request 1 */
-			au_writel(1<<(irq_nr-32), IC1_ASSIGNCLR);
-		else	     /* assign to interrupt request 0 */
-			au_writel(1<<(irq_nr-32), IC1_ASSIGNSET);
-		au_writel(1<<(irq_nr-32), IC1_SRCSET);
-		au_writel(1<<(irq_nr-32), IC1_MASKCLR);
-		au_writel(1<<(irq_nr-32), IC1_WAKECLR);
-	}
-	else {
-		switch (type) {
-			case INTC_INT_RISE_EDGE: /* 0:0:1 */
-				au_writel(1<<irq_nr, IC0_CFG2CLR);
-				au_writel(1<<irq_nr, IC0_CFG1CLR);
-				au_writel(1<<irq_nr, IC0_CFG0SET);
-				break;
-			case INTC_INT_FALL_EDGE: /* 0:1:0 */
-				au_writel(1<<irq_nr, IC0_CFG2CLR);
-				au_writel(1<<irq_nr, IC0_CFG1SET);
-				au_writel(1<<irq_nr, IC0_CFG0CLR);
-				break;
-			case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */
-				au_writel(1<<irq_nr, IC0_CFG2CLR);
-				au_writel(1<<irq_nr, IC0_CFG1SET);
-				au_writel(1<<irq_nr, IC0_CFG0SET);
-				break;
-			case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
-				au_writel(1<<irq_nr, IC0_CFG2SET);
-				au_writel(1<<irq_nr, IC0_CFG1CLR);
-				au_writel(1<<irq_nr, IC0_CFG0SET);
-				break;
-			case INTC_INT_LOW_LEVEL: /* 1:1:0 */
-				au_writel(1<<irq_nr, IC0_CFG2SET);
-				au_writel(1<<irq_nr, IC0_CFG1SET);
-				au_writel(1<<irq_nr, IC0_CFG0CLR);
-				break;
-			case INTC_INT_DISABLED: /* 0:0:0 */
-				au_writel(1<<irq_nr, IC0_CFG0CLR);
-				au_writel(1<<irq_nr, IC0_CFG1CLR);
-				au_writel(1<<irq_nr, IC0_CFG2CLR);
-				break;
-			default: /* disable the interrupt */
-				printk("unexpected int type %d (irq %d)\n", type, irq_nr);
-				au_writel(1<<irq_nr, IC0_CFG0CLR);
-				au_writel(1<<irq_nr, IC0_CFG1CLR);
-				au_writel(1<<irq_nr, IC0_CFG2CLR);
-				return;
-		}
-		if (int_req) /* assign to interrupt request 1 */
-			au_writel(1<<irq_nr, IC0_ASSIGNCLR);
-		else	     /* assign to interrupt request 0 */
-			au_writel(1<<irq_nr, IC0_ASSIGNSET);
-		au_writel(1<<irq_nr, IC0_SRCSET);
-		au_writel(1<<irq_nr, IC0_MASKCLR);
-		au_writel(1<<irq_nr, IC0_WAKECLR);
-	}
-	au_sync();
-}
-
 
 static unsigned int startup_irq(unsigned int irq_nr)
 {
@@ -410,6 +309,117 @@ void startup_match20_interrupt(void)
 }
 #endif
 
+static void setup_local_irq(unsigned int irq_nr, int type, int int_req)
+{
+	if (irq_nr > AU1000_MAX_INTR) return;
+	/* Config2[n], Config1[n], Config0[n] */
+	if (irq_nr > AU1000_LAST_INTC0_INT) {
+		switch (type) {
+			case INTC_INT_RISE_EDGE: /* 0:0:1 */
+				au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG0SET);
+				irq_desc[irq_nr].handler = &rise_edge_irq_type;
+				break;
+			case INTC_INT_FALL_EDGE: /* 0:1:0 */
+				au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG1SET);
+				au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
+				irq_desc[irq_nr].handler = &fall_edge_irq_type;
+				break;
+			case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */
+				au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG1SET);
+				au_writel(1<<(irq_nr-32), IC1_CFG0SET);
+				irq_desc[irq_nr].handler = &either_edge_irq_type;
+				break;
+			case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
+				au_writel(1<<(irq_nr-32), IC1_CFG2SET);
+				au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG0SET);
+				irq_desc[irq_nr].handler = &level_irq_type;
+				break;
+			case INTC_INT_LOW_LEVEL: /* 1:1:0 */
+				au_writel(1<<(irq_nr-32), IC1_CFG2SET);
+				au_writel(1<<(irq_nr-32), IC1_CFG1SET);
+				au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
+				irq_desc[irq_nr].handler = &level_irq_type;
+				break;
+			case INTC_INT_DISABLED: /* 0:0:0 */
+				au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
+				break;
+			default: /* disable the interrupt */
+				printk("unexpected int type %d (irq %d)\n", type, irq_nr);
+				au_writel(1<<(irq_nr-32), IC1_CFG0CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG1CLR);
+				au_writel(1<<(irq_nr-32), IC1_CFG2CLR);
+				return;
+		}
+		if (int_req) /* assign to interrupt request 1 */
+			au_writel(1<<(irq_nr-32), IC1_ASSIGNCLR);
+		else	     /* assign to interrupt request 0 */
+			au_writel(1<<(irq_nr-32), IC1_ASSIGNSET);
+		au_writel(1<<(irq_nr-32), IC1_SRCSET);
+		au_writel(1<<(irq_nr-32), IC1_MASKCLR);
+		au_writel(1<<(irq_nr-32), IC1_WAKECLR);
+	}
+	else {
+		switch (type) {
+			case INTC_INT_RISE_EDGE: /* 0:0:1 */
+				au_writel(1<<irq_nr, IC0_CFG2CLR);
+				au_writel(1<<irq_nr, IC0_CFG1CLR);
+				au_writel(1<<irq_nr, IC0_CFG0SET);
+				irq_desc[irq_nr].handler = &rise_edge_irq_type;
+				break;
+			case INTC_INT_FALL_EDGE: /* 0:1:0 */
+				au_writel(1<<irq_nr, IC0_CFG2CLR);
+				au_writel(1<<irq_nr, IC0_CFG1SET);
+				au_writel(1<<irq_nr, IC0_CFG0CLR);
+				irq_desc[irq_nr].handler = &fall_edge_irq_type;
+				break;
+			case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */
+				au_writel(1<<irq_nr, IC0_CFG2CLR);
+				au_writel(1<<irq_nr, IC0_CFG1SET);
+				au_writel(1<<irq_nr, IC0_CFG0SET);
+				irq_desc[irq_nr].handler = &either_edge_irq_type;
+				break;
+			case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
+				au_writel(1<<irq_nr, IC0_CFG2SET);
+				au_writel(1<<irq_nr, IC0_CFG1CLR);
+				au_writel(1<<irq_nr, IC0_CFG0SET);
+				irq_desc[irq_nr].handler = &level_irq_type;
+				break;
+			case INTC_INT_LOW_LEVEL: /* 1:1:0 */
+				au_writel(1<<irq_nr, IC0_CFG2SET);
+				au_writel(1<<irq_nr, IC0_CFG1SET);
+				au_writel(1<<irq_nr, IC0_CFG0CLR);
+				irq_desc[irq_nr].handler = &level_irq_type;
+				break;
+			case INTC_INT_DISABLED: /* 0:0:0 */
+				au_writel(1<<irq_nr, IC0_CFG0CLR);
+				au_writel(1<<irq_nr, IC0_CFG1CLR);
+				au_writel(1<<irq_nr, IC0_CFG2CLR);
+				break;
+			default: /* disable the interrupt */
+				printk("unexpected int type %d (irq %d)\n", type, irq_nr);
+				au_writel(1<<irq_nr, IC0_CFG0CLR);
+				au_writel(1<<irq_nr, IC0_CFG1CLR);
+				au_writel(1<<irq_nr, IC0_CFG2CLR);
+				return;
+		}
+		if (int_req) /* assign to interrupt request 1 */
+			au_writel(1<<irq_nr, IC0_ASSIGNCLR);
+		else	     /* assign to interrupt request 0 */
+			au_writel(1<<irq_nr, IC0_ASSIGNSET);
+		au_writel(1<<irq_nr, IC0_SRCSET);
+		au_writel(1<<irq_nr, IC0_MASKCLR);
+		au_writel(1<<irq_nr, IC0_WAKECLR);
+	}
+	au_sync();
+}
+
 
 void __init init_IRQ(void)
 {
@@ -417,7 +427,9 @@ void __init init_IRQ(void)
 	unsigned long cp0_status;
 	au1xxx_irq_map_t *imp;
 	extern au1xxx_irq_map_t au1xxx_irq_map[];
+	extern au1xxx_irq_map_t au1xxx_ic0_map[];
 	extern int au1xxx_nr_irqs;
+	extern int au1xxx_ic0_nr_irqs;
 
 	cp0_status = read_c0_status();
 	memset(irq_desc, 0, sizeof(irq_desc));
@@ -425,45 +437,43 @@ void __init init_IRQ(void)
 
 	init_generic_irq();
 
-	for (i = 0; i <= AU1000_MAX_INTR; i++) {
-		/* default is active high, level interrupt */
-		setup_local_irq(i, INTC_INT_HIGH_LEVEL, 0);
-		irq_desc[i].handler = &level_irq_type;
+	/* Initialize interrupt controllers to a safe state.
+	*/
+	au_writel(0xffffffff, IC0_CFG0CLR);
+	au_writel(0xffffffff, IC0_CFG1CLR);
+	au_writel(0xffffffff, IC0_CFG2CLR);
+	au_writel(0xffffffff, IC0_MASKCLR);
+	au_writel(0xffffffff, IC0_ASSIGNSET);
+	au_writel(0xffffffff, IC0_WAKECLR);
+	au_writel(0xffffffff, IC0_SRCSET);
+	au_writel(0xffffffff, IC0_FALLINGCLR);
+	au_writel(0xffffffff, IC0_RISINGCLR);
+	au_writel(0x00000000, IC0_TESTBIT);
+
+	au_writel(0xffffffff, IC1_CFG0CLR);
+	au_writel(0xffffffff, IC1_CFG1CLR);
+	au_writel(0xffffffff, IC1_CFG2CLR);
+	au_writel(0xffffffff, IC1_MASKCLR);
+	au_writel(0xffffffff, IC1_ASSIGNSET);
+	au_writel(0xffffffff, IC1_WAKECLR);
+	au_writel(0xffffffff, IC1_SRCSET);
+	au_writel(0xffffffff, IC1_FALLINGCLR);
+	au_writel(0xffffffff, IC1_RISINGCLR);
+	au_writel(0x00000000, IC1_TESTBIT);
+
+	/* Initialize IC0, which is fixed per processor.
+	*/
+	imp = au1xxx_ic0_map;
+	for (i=0; i<au1xxx_ic0_nr_irqs; i++) {
+		setup_local_irq(imp->im_irq, imp->im_type, imp->im_request);
+		imp++;
 	}
 
 	/* Now set up the irq mapping for the board.
 	*/
 	imp = au1xxx_irq_map;
 	for (i=0; i<au1xxx_nr_irqs; i++) {
-
 		setup_local_irq(imp->im_irq, imp->im_type, imp->im_request);
-
-		switch (imp->im_type) {
-
-		case INTC_INT_HIGH_LEVEL:
-			irq_desc[imp->im_irq].handler = &level_irq_type;
-			break;
-
-		case INTC_INT_LOW_LEVEL:
-			irq_desc[imp->im_irq].handler = &level_irq_type;
-			break;
-
-		case INTC_INT_RISE_EDGE:
-			irq_desc[imp->im_irq].handler = &rise_edge_irq_type;
-			break;
-
-		case INTC_INT_FALL_EDGE:
-			irq_desc[imp->im_irq].handler = &fall_edge_irq_type;
-			break;
-
-		case INTC_INT_RISE_AND_FALL_EDGE:
-			irq_desc[imp->im_irq].handler = &either_edge_irq_type;
-			break;
-
-		default:
-			panic("Unknown au1xxx irq map");
-			break;
-		}
 		imp++;
 	}
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/common/pci_fixup.c linux-2.4.29-pre3/arch/mips/au1000/common/pci_fixup.c
--- linux-2.4.28/arch/mips/au1000/common/pci_fixup.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/common/pci_fixup.c	2004-12-22 16:07:18.908302056 +0000
@@ -54,9 +54,7 @@
 #endif
 
 static void fixup_resource(int r_num, struct pci_dev *dev) ;
-#if defined( CONFIG_SOC_AU1500 ) || defined( CONFIG_SOC_AU1550 )
 static unsigned long virt_io_addr;
-#endif
 
 void __init pcibios_fixup_resources(struct pci_dev *dev)
 {
@@ -66,8 +64,6 @@ void __init pcibios_fixup_resources(stru
 void __init pcibios_fixup(void)
 {
 #if defined( CONFIG_SOC_AU1500 ) || defined( CONFIG_SOC_AU1550 )
-	int i;
-	struct pci_dev *dev;
 	
 	virt_io_addr = (unsigned long)ioremap(Au1500_PCI_IO_START, 
 			Au1500_PCI_IO_END - Au1500_PCI_IO_START + 1);
@@ -106,9 +102,10 @@ void __init pcibios_fixup(void)
 void __init pcibios_fixup_irqs(void)
 {
 #if defined( CONFIG_SOC_AU1500 ) || defined( CONFIG_SOC_AU1550 )
-	unsigned int slot, func;
+	unsigned int slot;
 	unsigned char pin;
 	struct pci_dev *dev;
+	extern int au1xxx_pci_irqmap(struct pci_dev *dev, unsigned char idsel, unsigned char pin);
 
 	pci_for_each_dev(dev) {
 		if (dev->bus->number != 0)
@@ -116,26 +113,9 @@ void __init pcibios_fixup_irqs(void)
 
 		dev->irq = 0xff;
 		slot = PCI_SLOT(dev->devfn);
-#if defined( CONFIG_SOC_AU1500 )
-		switch (slot) {
-			case 12:
-			case 13:
-			default:
-				dev->irq = AU1000_PCI_INTA;
-				break;
-		}
-#elif defined( CONFIG_SOC_AU1550 )
-		switch (slot) {
-			default:
-			case 12:
-				dev->irq = AU1000_PCI_INTA;
-				break;
-			case 13:
-				dev->irq = AU1000_PCI_INTB;
-				break;
-		}
-#endif
-
+		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+		dev->irq = au1xxx_pci_irqmap(dev, slot, pin);
+		//printk("Bus %d Dev %d Pin %d Irq %d\n", dev->bus->number, slot, pin, dev->irq);
 		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
 		DBG("slot %d irq %d\n", slot, dev->irq);
 	}
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/common/power.c linux-2.4.29-pre3/arch/mips/au1000/common/power.c
--- linux-2.4.28/arch/mips/au1000/common/power.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/common/power.c	2004-12-22 16:05:31.528626248 +0000
@@ -319,7 +319,7 @@ static int pm_do_freq(ctl_table * ctl, i
 	unsigned long val, pll;
 #define TMPBUFLEN 64
 #define MAX_CPU_FREQ 396
-	char buf[8], *p;
+	char buf[TMPBUFLEN], *p;
 	unsigned long flags, intc0_mask, intc1_mask;
 	unsigned long old_baud_base, old_cpu_freq, baud_rate, old_clk,
 	    old_refresh;
@@ -357,7 +357,7 @@ static int pm_do_freq(ctl_table * ctl, i
 		old_cpu_freq = get_au1x00_speed();
 
 		new_cpu_freq = pll * 12 * 1000000;
-		new_baud_base = (new_cpu_freq / 4) / 16;
+	        new_baud_base =  (new_cpu_freq / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16));
 		set_au1x00_speed(new_cpu_freq);
 		set_au1x00_uart_baud_base(new_baud_base);
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/common/prom.c linux-2.4.29-pre3/arch/mips/au1000/common/prom.c
--- linux-2.4.28/arch/mips/au1000/common/prom.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/common/prom.c	2004-12-22 16:07:12.582263760 +0000
@@ -68,6 +68,11 @@ void  prom_init_cmdline(void)
 	actr = 1; /* Always ignore argv[0] */
 
 	cp = &(arcs_cmdline[0]);
+#ifdef CONFIG_CMDLINE_BOOL
+	strcpy(cp, CONFIG_CMDLINE);
+	cp += strlen(CONFIG_CMDLINE);
+	*cp++ = ' ';
+#endif
 	while(actr < prom_argc) {
 	        strcpy(cp, prom_argv[actr]);
 		cp += strlen(prom_argv[actr]);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/common/reset.c linux-2.4.29-pre3/arch/mips/au1000/common/reset.c
--- linux-2.4.28/arch/mips/au1000/common/reset.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/common/reset.c	2004-12-22 16:05:33.743289568 +0000
@@ -42,6 +42,7 @@ extern int au_sleep(void);
 void au1000_restart(char *command)
 {
 	/* Set all integrated peripherals to disabled states */
+	extern void board_reset (void);
 	u32 prid = read_c0_prid();
 
 	printk(KERN_NOTICE "\n** Resetting Integrated Peripherals\n");
@@ -120,6 +121,29 @@ void au1000_restart(char *command)
 		au_writel(0x00, 0xb1900064); /* sys_auxpll */
 		au_writel(0x00, 0xb1900100); /* sys_pininputen */
 		break;
+	case 0x03000000: /* Au1550 */
+		au_writel(0x00, 0xb1a00004); /* psc 0 */
+		au_writel(0x00, 0xb1b00004); /* psc 1 */
+		au_writel(0x00, 0xb0a00004); /* psc 2 */
+		au_writel(0x00, 0xb0b00004); /* psc 3 */
+		au_writel(0x00, 0xb017fffc); /* usbh_enable */
+		au_writel(0x00, 0xb0200058); /* usbd_enable */
+		au_writel(0x00, 0xb4004104); /* mac dma */
+		au_writel(0x00, 0xb4004114); /* mac dma */
+		au_writel(0x00, 0xb4004124); /* mac dma */
+		au_writel(0x00, 0xb4004134); /* mac dma */
+		au_writel(0x00, 0xb1520000); /* macen0 */
+		au_writel(0x00, 0xb1520004); /* macen1 */
+		au_writel(0x00, 0xb1100100); /* uart0_enable */
+		au_writel(0x00, 0xb1200100); /* uart1_enable */
+		au_writel(0x00, 0xb1400100); /* uart3_enable */
+		au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */
+		au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */
+		au_writel(0x00, 0xb1900028); /* sys_clksrc */
+		au_writel(0x10, 0xb1900060); /* sys_cpupll */
+		au_writel(0x00, 0xb1900064); /* sys_auxpll */
+		au_writel(0x00, 0xb1900100); /* sys_pininputen */
+		break;
 
 	default:
 		break;
@@ -130,18 +154,26 @@ void au1000_restart(char *command)
 	flush_cache_all();
 	write_c0_wired(0);
 
-#if defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500)
-	/* Do a HW reset if the board can do it */
-
-	au_writel(0x00000000, 0xAE00001C);
-#endif
+	/* Give board a chance to do a hardware reset */
+	board_reset();
 
+	/* Jump to the beggining in case board_reset() is empty */
 	__asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
 }
 
 void au1000_halt(void)
 {
+#if defined(CONFIG_MIPS_PB1550)
+	/* power off system */
+	printk("\n** Powering off Pb1550\n");
+	au_writew(au_readw(0xAF00001C) | (3<<14), 0xAF00001C); 
+	au_sync();
+	while(1); /* should not get here */
+#endif
 	printk(KERN_NOTICE "\n** You can safely turn off the power\n");
+#ifdef CONFIG_MIPS_MIRAGE
+	au_writel((1 << 26) | (1 << 10), GPIO2_OUTPUT);
+#endif
 #ifdef CONFIG_PM
 	au_sleep();
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/common/setup.c linux-2.4.29-pre3/arch/mips/au1000/common/setup.c
--- linux-2.4.28/arch/mips/au1000/common/setup.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/common/setup.c	2004-12-22 16:07:32.411249296 +0000
@@ -52,6 +52,7 @@ extern void * __rd_start, * __rd_end;
 #endif
 
 #ifdef CONFIG_BLK_DEV_IDE
+extern struct ide_ops no_ide_ops;
 extern struct ide_ops std_ide_ops;
 extern struct ide_ops *ide_ops;
 #endif
@@ -64,22 +65,47 @@ extern void au1000_halt(void);
 extern void au1000_power_off(void);
 extern struct resource ioport_resource;
 extern struct resource iomem_resource;
-#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_SOC_AU1500)
+#if defined(CONFIG_64BIT_PHYS_ADDR) && (defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550))
 extern phys_t (*fixup_bigphys_addr)(phys_t phys_addr, phys_t size);
 static phys_t au1500_fixup_bigphys_addr(phys_t phys_addr, phys_t size);
 #endif
 extern void au1xxx_time_init(void);
 extern void au1xxx_timer_setup(void);
+extern void set_cpuspec(void);
 
 void __init au1x00_setup(void)
 {
+	struct	cpu_spec *sp;
 	char *argptr;
+	unsigned long prid, cpupll, bclk;
 
-	/* Various early Au1000 Errata corrected by this */
-	set_c0_config(1<<19); /* Config[OD] */
+	set_cpuspec();
+	sp = cur_cpu_spec[0];
 
 	board_setup();  /* board specific setup */
 
+	prid = read_c0_prid();
+	cpupll = (au_readl(0xB1900060) & 0x3F) * 12;
+
+	printk("%s (PRId %08X) @ %dMHZ\n", sp->cpu_name, prid, cpupll);
+
+	bclk = sp->cpu_bclk;
+	if (bclk) {
+		/* Enable BCLK switching */
+		bclk = au_readl(0xB190003C);
+		au_writel(bclk | 0x60, 0xB190003C);
+		printk("BCLK switching enabled!\n");
+	}
+
+	if (sp->cpu_od) {
+		/* Various early Au1000 Errata corrected by this */
+		set_c0_config(1<<19); /* Set Config[OD] */
+	}
+	else {
+		/* Clear to obtain best system bus performance */
+		clear_c0_config(1<<19); /* Clear Config[OD] */
+ 	}
+
 	argptr = prom_getcmdline();
 
 #ifdef CONFIG_AU1X00_SERIAL_CONSOLE
@@ -128,7 +154,7 @@ void __init au1x00_setup(void)
 	_machine_restart = au1000_restart;
 	_machine_halt = au1000_halt;
 	_machine_power_off = au1000_power_off;
-#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_SOC_AU1500)
+#if defined(CONFIG_64BIT_PHYS_ADDR) && (defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550))
 	fixup_bigphys_addr = au1500_fixup_bigphys_addr;
 #endif
 
@@ -185,7 +211,7 @@ void __init au1x00_setup(void)
 #ifdef CONFIG_BLK_DEV_IDE
 	/* Board setup takes precedence for unique devices.
 	*/
-	if (ide_ops == NULL)
+	if ((ide_ops == NULL) || (ide_ops == &no_ide_ops))
 		ide_ops = &std_ide_ops;
 #endif
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/common/time.c linux-2.4.29-pre3/arch/mips/au1000/common/time.c
--- linux-2.4.28/arch/mips/au1000/common/time.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/common/time.c	2004-12-22 16:06:22.945809648 +0000
@@ -39,6 +39,7 @@
 #include <linux/sched.h>
 #include <linux/spinlock.h>
 
+#include <asm/compiler.h>
 #include <asm/mipsregs.h>
 #include <asm/ptrace.h>
 #include <asm/time.h>
@@ -49,10 +50,6 @@
 #include <linux/mc146818rtc.h>
 #include <linux/timex.h>
 
-#if !defined(CONFIG_NEW_TIME_C)
-#error "Alchemy processors need CONFIG_NEW_TIME_C defined"
-#endif
-
 extern void startup_match20_interrupt(void);
 extern void do_softirq(void);
 extern volatile unsigned long wall_jiffies;
@@ -351,9 +348,9 @@ static unsigned long do_fast_cp0_gettime
 
 	__asm__("multu\t%1,%2\n\t"
 		"mfhi\t%0"
-		:"=r" (res)
-		:"r" (count),
-		 "r" (quotient));
+		: "=r" (res)
+		: "r" (count), "r" (quotient)
+		: "hi", "lo", GCC_REG_ACCUM);
 
 	/*
  	 * Due to possible jiffies inconsistencies, we need to check 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/csb250/irqmap.c linux-2.4.29-pre3/arch/mips/au1000/csb250/irqmap.c
--- linux-2.4.28/arch/mips/au1000/csb250/irqmap.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/csb250/irqmap.c	2004-12-22 16:07:31.197433824 +0000
@@ -48,53 +48,13 @@
 #include <asm/au1000.h>
 
 au1xxx_irq_map_t au1xxx_irq_map[] = {
-	{ AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0},
 
-	{ AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0},
-
-	{ AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
 	{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
-
-	{ AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
-
-	{ AU1000_PCI_INTA, INTC_INT_LOW_LEVEL, 0 },
-	{ AU1000_PCI_INTB, INTC_INT_LOW_LEVEL, 0 },
-	{ AU1000_PCI_INTC, INTC_INT_LOW_LEVEL, 0 },
-	{ AU1000_PCI_INTD, INTC_INT_LOW_LEVEL, 0 },
 	{ AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
 	{ AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 },
 	{ AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 },
 	{ AU1500_GPIO_205, INTC_INT_LOW_LEVEL, 0 },
 	{ AU1500_GPIO_207, INTC_INT_LOW_LEVEL, 0 },
-
-	{ AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_USB_DEV_REQ_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
-
-	/* Careful if you change match 2 request!
-	 * The interrupt handler is called directly
-	 * from the low level dispatch code.
-	 */
-	{ AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
 };
 
 int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/db1x00/Makefile linux-2.4.29-pre3/arch/mips/au1000/db1x00/Makefile
--- linux-2.4.28/arch/mips/au1000/db1x00/Makefile	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/db1x00/Makefile	2004-12-22 16:06:24.894513400 +0000
@@ -10,13 +10,11 @@
 # unless it's something special (ie not a .c file).
 #
 
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
 
 O_TARGET := db1x00.o
 
 obj-y := init.o board_setup.o irqmap.o
+obj-$(CONFIG_WM97XX_COMODULE) += mirage_ts.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/db1x00/board_setup.c linux-2.4.29-pre3/arch/mips/au1000/db1x00/board_setup.c
--- linux-2.4.28/arch/mips/au1000/db1x00/board_setup.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/db1x00/board_setup.c	2004-12-22 16:07:12.583263608 +0000
@@ -48,14 +48,22 @@
 
 extern struct rtc_ops no_rtc_ops;
 
+/* not correct for db1550 */
 static BCSR * const bcsr = (BCSR *)0xAE000000;
 
+void board_reset (void)
+{
+	/* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
+	au_writel(0x00000000, 0xAE00001C);
+}
+
 void __init board_setup(void)
 {
 	u32 pin_func;
 
 	rtc_ops = &no_rtc_ops;
 
+	/* not valid for 1550 */
 #ifdef CONFIG_AU1X00_USB_DEVICE
 	// 2nd USB port is USB device
 	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);
@@ -73,6 +81,35 @@ void __init board_setup(void)
 #endif
 	au_writel(0, 0xAE000010); /* turn off pcmcia power */
 
+#ifdef CONFIG_MIPS_MIRAGE
+	/* enable GPIO[31:0] inputs */
+	au_writel(0, SYS_PININPUTEN);
+
+	/* GPIO[20] is output, tristate the other input primary GPIO's */
+	au_writel((u32)(~(1<<20)), SYS_TRIOUTCLR);
+
+	/* set GPIO[210:208] instead of SSI_0 */
+	pin_func = au_readl(SYS_PINFUNC) | (u32)(1);
+
+	/* set GPIO[215:211] for LED's */
+	pin_func |= (u32)((5<<2));
+
+	/* set GPIO[214:213] for more LED's */
+	pin_func |= (u32)((5<<12));
+
+	/* set GPIO[207:200] instead of PCMCIA/LCD */
+	pin_func |= (u32)((3<<17));
+	au_writel(pin_func, SYS_PINFUNC);
+
+	/* Enable speaker amplifier.  This should
+	 * be part of the audio driver.
+	 */
+	au_writel(au_readl(GPIO2_DIR) | 0x200, GPIO2_DIR);
+	au_writel(0x02000200, GPIO2_OUTPUT);
+#endif
+
+	au_sync();
+
 #ifdef CONFIG_MIPS_DB1000
     printk("AMD Alchemy Au1000/Db1000 Board\n");
 #endif
@@ -88,4 +125,7 @@ void __init board_setup(void)
 #ifdef CONFIG_MIPS_MIRAGE
     printk("AMD Alchemy Mirage Board\n");
 #endif
+#ifdef CONFIG_MIPS_DB1550
+    printk("AMD Alchemy Au1550/Db1550 Board\n");
+#endif
 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/db1x00/irqmap.c linux-2.4.29-pre3/arch/mips/au1000/db1x00/irqmap.c
--- linux-2.4.28/arch/mips/au1000/db1x00/irqmap.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/db1x00/irqmap.c	2004-12-22 16:05:44.527650096 +0000
@@ -48,71 +48,95 @@
 #include <asm/au1000.h>
 
 au1xxx_irq_map_t au1xxx_irq_map[] = {
-	{ AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0},
-
-	{ AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0},
-
-	{ AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
-#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_MIRAGE)
-	{ AU1000_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
-#endif
+
 #ifndef CONFIG_MIPS_MIRAGE
-	{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
+#ifdef CONFIG_MIPS_DB1550
+	{ AU1000_GPIO_3, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 0 IRQ#
+	{ AU1000_GPIO_5, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 1 IRQ#
+#else
+	{ AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 0 Fully_Interted#
+	{ AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 0 STSCHG#
+	{ AU1000_GPIO_2, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 0 IRQ#
+
+	{ AU1000_GPIO_3, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 1 Fully_Interted#
+	{ AU1000_GPIO_4, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 1 STSCHG#
+	{ AU1000_GPIO_5, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 1 IRQ#
 #endif
+#else
+	{ AU1000_GPIO_7, INTC_INT_RISE_EDGE, 0 }, /* touchscreen pendown */
+#endif
+};
 
-	{ AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
+int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t);
+
+#ifdef CONFIG_PCI
 
 #ifdef CONFIG_SOC_AU1500
-	{ AU1000_PCI_INTA, INTC_INT_LOW_LEVEL, 0 },
-	{ AU1000_PCI_INTB, INTC_INT_LOW_LEVEL, 0 },
-	{ AU1000_PCI_INTC, INTC_INT_LOW_LEVEL, 0 },
-	{ AU1000_PCI_INTD, INTC_INT_LOW_LEVEL, 0 },
+#define INTA AU1000_PCI_INTA
+#define INTB AU1000_PCI_INTB
+#define INTC AU1000_PCI_INTC
+#define INTD AU1000_PCI_INTD
+#endif
+
+#ifdef CONFIG_SOC_AU1550
+#define INTA AU1550_PCI_INTA
+#define INTB AU1550_PCI_INTB
+#define INTC AU1550_PCI_INTC
+#define INTD AU1550_PCI_INTD
 #endif
 
+#define INTX 0xFF /* not valid */
+
+int __init
+au1xxx_pci_irqmap(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+	/*
+	 *	PCI IDSEL/INTPIN->INTLINE
+	 *	A       B       C       D
+	 */
 #ifdef CONFIG_MIPS_DB1500
-	{ AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
-	{ AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 },
-	{ AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 },
-	{ AU1500_GPIO_205, INTC_INT_LOW_LEVEL, 0 },
-	{ AU1500_GPIO_207, INTC_INT_LOW_LEVEL, 0 },
+	static char pci_irq_table[][4] =
+	{
+		{INTA, INTX, INTX, INTX},   /* IDSEL 12 - HPT371   */
+		{INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot */
+	};
+	const long min_idsel = 12, max_idsel = 13, irqs_per_slot = 4;
 #endif
 
-#ifndef CONFIG_MIPS_MIRAGE
-	{ AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 0 Fully_Interted#
-	{ AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 0 STSCHG#
-	{ AU1000_GPIO_2, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 0 IRQ#
+#ifdef CONFIG_MIPS_BOSPORUS
+	static char pci_irq_table[][4] =
+	{
+		{INTA, INTB, INTX, INTX},   /* IDSEL 11 - miniPCI  */
+		{INTA, INTX, INTX, INTX},   /* IDSEL 12 - SN1741   */
+		{INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot */
+	};
+	const long min_idsel = 11, max_idsel = 13, irqs_per_slot = 4;
+#endif
 
-	{ AU1000_GPIO_3, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 1 Fully_Interted#
-	{ AU1000_GPIO_4, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 1 STSCHG#
-	{ AU1000_GPIO_5, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 1 IRQ#
+#ifdef CONFIG_MIPS_MIRAGE
+	static char pci_irq_table[][4] =
+	{
+		{INTD, INTX, INTX, INTX},   /* IDSEL 11 - SMI VGX */
+		{INTX, INTX, INTC, INTX},   /* IDSEL 12 - PNX1300 */
+		{INTA, INTB, INTX, INTX},   /* IDSEL 13 - miniPCI */
+	};
+	const long min_idsel = 11, max_idsel = 13, irqs_per_slot = 4;
+#endif
+
+#ifdef CONFIG_MIPS_DB1550
+	static char pci_irq_table[][4] =
+	{
+		{INTC, INTX, INTX, INTX},   /* IDSEL 11 - on-board HPT371    */
+		{INTB, INTC, INTD, INTA},   /* IDSEL 12 - PCI slot 2 (left)  */
+		{INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot 1 (right) */
+	};
+	const long min_idsel = 11, max_idsel = 13, irqs_per_slot = 4;
+#endif
+#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1500)
+	return PCI_IRQ_TABLE_LOOKUP;
+#else
+	return 0;
 #endif
-	{ AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_USB_DEV_REQ_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
-
-	/* Careful if you change match 2 request!
-	 * The interrupt handler is called directly
-	 * from the low level dispatch code.
-	 */
-	{ AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
 };
+#endif
 
-int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/db1x00/mirage_ts.c linux-2.4.29-pre3/arch/mips/au1000/db1x00/mirage_ts.c
--- linux-2.4.28/arch/mips/au1000/db1x00/mirage_ts.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/db1x00/mirage_ts.c	2004-12-22 16:06:21.288061664 +0000
@@ -0,0 +1,263 @@
+/*
+ * linux/arch/mips/au1000/db1x00/mirage_ts.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Glue between Mirage board-specific touchscreen pieces
+ *	and generic Wolfson Codec touchscreen support.
+ *
+ *	Based on pb1100_ts.c used in Hydrogen II.
+ *
+ * Copyright (c) 2003 Embedded Edge, LLC
+ *		dan@embeddededge.com
+ *
+ *  This program is free software; you can redistribute	 it and/or modify it
+ *  under  the terms of	 the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the	License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
+ *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
+ *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/poll.h>
+#include <linux/proc_fs.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+
+#include <asm/segment.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/delay.h>
+#include <asm/au1000.h>
+
+/*
+ *  Imported interface to Wolfson Codec driver.
+ */
+extern void *wm97xx_ts_get_handle(int which);
+extern int wm97xx_ts_ready(void* ts_handle);
+extern void wm97xx_ts_set_cal(void* ts_handle, int xscale, int xtrans, int yscale, int ytrans);
+extern u16 wm97xx_ts_get_ac97(void* ts_handle, u8 reg);
+extern void wm97xx_ts_set_ac97(void* ts_handle, u8 reg, u16 val);
+extern int wm97xx_ts_read_data(void* ts_handle, long* x, long* y, long* pressure);
+extern void wm97xx_ts_send_data(void* ts_handle, long x, long y, long z);
+
+int wm97xx_comodule_present = 1;
+
+
+#define TS_NAME "mirage_ts"
+
+#define err(format, arg...) printk(KERN_ERR TS_NAME ": " format "\n" , ## arg)
+#define info(format, arg...) printk(KERN_INFO TS_NAME ": " format "\n" , ## arg)
+#define warn(format, arg...) printk(KERN_WARNING TS_NAME ": " format "\n" , ## arg)
+#define DPRINTK(format, arg...) printk(__FUNCTION__ ": " format "\n" , ## arg)
+
+
+#define PEN_DOWN_IRQ	AU1000_GPIO_7
+
+static struct task_struct *ts_task = 0;
+static DECLARE_COMPLETION(ts_complete);
+static DECLARE_WAIT_QUEUE_HEAD(pendown_wait);
+
+#ifdef CONFIG_WM97XX_FIVEWIRETS
+static int release_pressure = 1;
+#else
+static int release_pressure = 50;
+#endif
+
+typedef struct {
+   long x;
+   long y;
+} DOWN_EVENT;
+
+#define SAMPLE_RATE	50	/* samples per second */
+#define PEN_DEBOUNCE	5	/* samples for settling - fn of SAMPLE_RATE */
+#define PEN_UP_TIMEOUT	10	/* in seconds */
+#define PEN_UP_SETTLE	5	/* samples per second */
+
+static struct {
+	int xscale;
+	int xtrans;
+	int yscale;
+	int ytrans;
+} mirage_ts_cal =
+{
+#if 0
+	xscale:   84,
+	xtrans: -157,
+	yscale:   66,
+	ytrans: -150,
+#else
+	xscale:   84,
+	xtrans: -150,
+	yscale:   66,
+	ytrans: -146,
+#endif
+};
+
+
+static void pendown_irq(int irqnr, void *devid, struct pt_regs *regs)
+{
+//DPRINTK("got one 0x%x", au_readl(SYS_PINSTATERD));
+	wake_up(&pendown_wait);
+}
+
+static int ts_thread(void *id)
+{
+	static int pen_was_down = 0;
+	static DOWN_EVENT pen_xy;
+	long x, y, z;
+	void *ts;	/* handle */
+	struct task_struct *tsk = current;
+	int timeout = HZ / SAMPLE_RATE;
+
+	ts_task = tsk;
+
+	daemonize();
+	tsk->tty = NULL;
+	tsk->policy = SCHED_FIFO;
+	tsk->rt_priority = 1;
+	strcpy(tsk->comm, "touchscreen");
+
+	/* only want to receive SIGKILL */
+	spin_lock_irq(&tsk->sigmask_lock);
+	siginitsetinv(&tsk->blocked, sigmask(SIGKILL));
+	recalc_sigpending(tsk);
+	spin_unlock_irq(&tsk->sigmask_lock);
+
+	/* get handle for codec */
+	ts = wm97xx_ts_get_handle(0);
+
+	/* proceed only after everybody is ready */
+	while ( ! wm97xx_ts_ready(ts) ) {
+		/* give a little time for initializations to complete */
+		interruptible_sleep_on_timeout(&pendown_wait, HZ / 4);
+	}
+
+	/* board-specific calibration */
+	wm97xx_ts_set_cal(ts,
+			mirage_ts_cal.xscale,
+			mirage_ts_cal.xtrans,
+			mirage_ts_cal.yscale,
+			mirage_ts_cal.ytrans);
+
+	/* route Wolfson pendown interrupts to our GPIO */
+	au_sync();
+	wm97xx_ts_set_ac97(ts, 0x4c, wm97xx_ts_get_ac97(ts, 0x4c) & ~0x0008);
+	au_sync();
+	wm97xx_ts_set_ac97(ts, 0x56, wm97xx_ts_get_ac97(ts, 0x56) & ~0x0008);
+	au_sync();
+	wm97xx_ts_set_ac97(ts, 0x52, wm97xx_ts_get_ac97(ts, 0x52) | 0x2008);
+	au_sync();
+
+	for (;;) {
+		interruptible_sleep_on_timeout(&pendown_wait, timeout);
+		disable_irq(PEN_DOWN_IRQ);
+		if (signal_pending(tsk)) {
+			break;
+		}
+
+		/* read codec */
+		if (!wm97xx_ts_read_data(ts, &x, &y, &z))
+			z = 0;	/* treat no-data and pen-up the same */
+
+		if (signal_pending(tsk)) {
+			break;
+		}
+
+		if (z >= release_pressure) {
+			y = ~y;	/* top to bottom */
+			if (pen_was_down > 1 /*&& pen_was_down < PEN_DEBOUNCE*/) {//THXXX
+				/* bounce ? */
+				x = pen_xy.x;
+				y = pen_xy.y;
+				--pen_was_down;
+			} else if (pen_was_down <= 1) {
+				pen_xy.x = x;
+				pen_xy.y = y;
+				if (pen_was_down)
+					wm97xx_ts_send_data(ts, x, y, z);
+				pen_was_down = PEN_DEBOUNCE;
+			}
+			//wm97xx_ts_send_data(ts, x, y, z);
+			timeout = HZ / SAMPLE_RATE;
+		} else {
+			if (pen_was_down) {
+				if (--pen_was_down)
+					z = release_pressure;
+				else //THXXX
+				wm97xx_ts_send_data(ts, pen_xy.x, pen_xy.y, z);
+			}
+			/* The pendown signal takes some time to settle after
+			 * reading the pen pressure so wait a little
+			 * before enabling the pen.
+			 */
+			if (! pen_was_down) {
+//				interruptible_sleep_on_timeout(&pendown_wait, HZ / PEN_UP_SETTLE);
+				timeout = HZ * PEN_UP_TIMEOUT;
+			}
+		}
+		enable_irq(PEN_DOWN_IRQ);
+	}
+	enable_irq(PEN_DOWN_IRQ);
+	ts_task = NULL;
+	complete(&ts_complete);
+	return 0;
+}
+
+static int __init ts_mirage_init(void)
+{
+	int ret;
+
+	/* pen down signal is connected to GPIO 7 */
+
+	ret = request_irq(PEN_DOWN_IRQ, pendown_irq, 0, "ts-pendown", NULL);
+	if (ret) {
+		err("unable to get pendown irq%d: [%d]", PEN_DOWN_IRQ, ret);
+		return ret;
+	}
+
+	lock_kernel();
+	ret = kernel_thread(ts_thread, NULL, CLONE_FS | CLONE_FILES);
+	if (ret < 0) {
+		unlock_kernel();
+		return ret;
+	}
+	unlock_kernel();
+
+	info("Mirage touchscreen IRQ initialized.");
+
+	return 0;
+}
+
+static void __exit ts_mirage_exit(void)
+{
+	if (ts_task) {
+		send_sig(SIGKILL, ts_task, 1);
+		wait_for_completion(&ts_complete);
+	}
+
+	free_irq(PEN_DOWN_IRQ, NULL);
+}
+
+module_init(ts_mirage_init);
+module_exit(ts_mirage_exit);
+
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/hydrogen3/Makefile linux-2.4.29-pre3/arch/mips/au1000/hydrogen3/Makefile
--- linux-2.4.28/arch/mips/au1000/hydrogen3/Makefile	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/hydrogen3/Makefile	2004-12-22 16:07:34.061998344 +0000
@@ -10,10 +10,7 @@
 # unless it's something special (ie not a .c file).
 #
 
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
 
 O_TARGET := hydrogen3.o
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/hydrogen3/board_setup.c linux-2.4.29-pre3/arch/mips/au1000/hydrogen3/board_setup.c
--- linux-2.4.28/arch/mips/au1000/hydrogen3/board_setup.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/hydrogen3/board_setup.c	2004-12-22 16:05:32.990404024 +0000
@@ -44,10 +44,13 @@
 #include <asm/reboot.h>
 #include <asm/pgtable.h>
 #include <asm/au1000.h>
-#include <asm/db1x00.h>
 
 extern struct rtc_ops no_rtc_ops;
 
+void board_reset (void)
+{
+}
+
 void __init board_setup(void)
 {
 	u32 pin_func;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/hydrogen3/irqmap.c linux-2.4.29-pre3/arch/mips/au1000/hydrogen3/irqmap.c
--- linux-2.4.28/arch/mips/au1000/hydrogen3/irqmap.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/hydrogen3/irqmap.c	2004-12-22 16:07:16.975595872 +0000
@@ -48,43 +48,9 @@
 #include <asm/au1000.h>
 
 au1xxx_irq_map_t au1xxx_irq_map[] = {
-	{ AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0},
 
-	{ AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0},
-
-	{ AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
-
-	{ AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
-
-//	{ AU1500_GPIO_205, INTC_INT_LOW_LEVEL, 0 },
-
-	{ AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_USB_DEV_REQ_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
-
-	/* Careful if you change match 2 request!
-	 * The interrupt handler is called directly
-	 * from the low level dispatch code.
-	 */
-	{ AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
+	/* { AU1500_GPIO_205, INTC_INT_LOW_LEVEL, 0 }, */
+	{ AU1000_GPIO_21, INTC_INT_LOW_LEVEL, 0 },
 };
 
 int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/mtx-1/Makefile linux-2.4.29-pre3/arch/mips/au1000/mtx-1/Makefile
--- linux-2.4.28/arch/mips/au1000/mtx-1/Makefile	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/mtx-1/Makefile	2004-12-22 16:07:30.173589472 +0000
@@ -11,10 +11,7 @@
 # unless it's something special (ie not a .c file).
 #
 
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
 
 O_TARGET := mtx-1.o
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/mtx-1/irqmap.c linux-2.4.29-pre3/arch/mips/au1000/mtx-1/irqmap.c
--- linux-2.4.28/arch/mips/au1000/mtx-1/irqmap.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/mtx-1/irqmap.c	2004-12-22 16:05:32.296509512 +0000
@@ -47,47 +47,37 @@
 #include <asm/system.h>
 #include <asm/au1000.h>
 
+/* Need to define this.
+*/
 au1xxx_irq_map_t au1xxx_irq_map[] = {
-	{ AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
-
-	{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0},
-
-	{ AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
-
-	{ AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
-
-	{ AU1000_PCI_INTA, INTC_INT_LOW_LEVEL, 0 },
-	{ AU1000_PCI_INTB, INTC_INT_LOW_LEVEL, 0 },
-	{ AU1000_PCI_INTC, INTC_INT_LOW_LEVEL, 0 },
-	{ AU1000_PCI_INTD, INTC_INT_LOW_LEVEL, 0 },
-
-	{ AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
-
-	{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
+	{ 0, 0, 0}
+};
 
-	{ AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_USB_DEV_REQ_INT, INTC_INT_RISE_EDGE, 0 },
+int au1xxx_nr_irqs = 0;
 
-	{ AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
+#ifdef CONFIG_PCI
 
-	/* Careful if you change match 2 request!
-	 * The interrupt handler is called directly
-	 * from the low level dispatch code.
+#define INTA AU1000_PCI_INTA
+#define INTB AU1000_PCI_INTB
+#define INTC AU1000_PCI_INTC
+#define INTD AU1000_PCI_INTD
+#define INTX 0xFF /* not valid */
+
+int __init
+au1xxx_pci_irqmap(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+	static char pci_irq_table[][4] =
+	/*
+	 *	PCI IDSEL/INTPIN->INTLINE
+	 *	A       B       C       D
 	 */
-	{ AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
+	{
+		{INTA, INTB, INTC, INTD},   /* IDSEL 0 */
+		{INTA, INTB, INTC, INTD},   /* IDSEL 1 */
+		{INTA, INTB, INTC, INTD},   /* IDSEL 2 */
+		{INTA, INTB, INTC, INTD},   /* IDSEL 3 */
+	};
+	const long min_idsel = 0, max_idsel = 3, irqs_per_slot = 4;
+	return PCI_IRQ_TABLE_LOOKUP;
 };
-
-int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t);
+#endif
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/pb1000/board_setup.c linux-2.4.29-pre3/arch/mips/au1000/pb1000/board_setup.c
--- linux-2.4.28/arch/mips/au1000/pb1000/board_setup.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/pb1000/board_setup.c	2004-12-22 16:05:45.392518616 +0000
@@ -54,6 +54,10 @@
 
 extern struct rtc_ops no_rtc_ops;
 
+void board_reset (void)
+{
+}
+
 void __init board_setup(void)
 {
 	u32 pin_func, static_cfg0;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/pb1000/irqmap.c linux-2.4.29-pre3/arch/mips/au1000/pb1000/irqmap.c
--- linux-2.4.28/arch/mips/au1000/pb1000/irqmap.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/pb1000/irqmap.c	2004-12-22 16:07:15.769779184 +0000
@@ -48,49 +48,7 @@
 #include <asm/au1000.h>
 
 au1xxx_irq_map_t au1xxx_irq_map[] = {
-	{ AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_UART1_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_UART2_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0},
-
-	{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0},
-
-	{ AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0},
-
-	{ AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
-
 	{ AU1000_GPIO_15, INTC_INT_LOW_LEVEL, 0 },
-	{ AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
-
-	{ AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_USB_DEV_REQ_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
-
-	/* Careful if you change match 2 request!
-	 * The interrupt handler is called directly
-	 * from the low level dispatch code.
-	 */
-	{ AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
 };
 
 int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/pb1100/board_setup.c linux-2.4.29-pre3/arch/mips/au1000/pb1100/board_setup.c
--- linux-2.4.28/arch/mips/au1000/pb1100/board_setup.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/pb1100/board_setup.c	2004-12-22 16:05:33.174376056 +0000
@@ -56,6 +56,12 @@
 extern struct rtc_ops pb1500_rtc_ops;
 #endif
 
+void board_reset (void)
+{
+    /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
+    au_writel(0x00000000, 0xAE00001C);
+}
+
 void __init board_setup(void)
 {
 	u32 pin_func;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/pb1100/irqmap.c linux-2.4.29-pre3/arch/mips/au1000/pb1100/irqmap.c
--- linux-2.4.28/arch/mips/au1000/pb1100/irqmap.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/pb1100/irqmap.c	2004-12-22 16:06:38.601429632 +0000
@@ -48,53 +48,10 @@
 #include <asm/au1000.h>
 
 au1xxx_irq_map_t au1xxx_irq_map[] = {
-	{ AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_UART1_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
-
-	{ AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0},
-
-	{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0},
-
-	{ AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0},
-
-	{ AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
-
-	{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
-
-	{ AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
 	{ AU1000_GPIO_9, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card Fully_Interted#
 	{ AU1000_GPIO_10, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card STSCHG#
 	{ AU1000_GPIO_11, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card IRQ#
 	{ AU1000_GPIO_13, INTC_INT_LOW_LEVEL, 0 }, // DC_IRQ#
-	{ AU1000_GPIO_23, INTC_INT_LOW_LEVEL, 0 }, // 2-wire SCL
-
-	{ AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_USB_DEV_REQ_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
-
-	/* Careful if you change match 2 request!
-	 * The interrupt handler is called directly
-	 * from the low level dispatch code.
-	 */
-	{ AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
 };
 
 int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/pb1500/board_setup.c linux-2.4.29-pre3/arch/mips/au1000/pb1500/board_setup.c
--- linux-2.4.28/arch/mips/au1000/pb1500/board_setup.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/pb1500/board_setup.c	2004-12-22 16:06:41.208033368 +0000
@@ -56,6 +56,12 @@
 extern struct rtc_ops pb1500_rtc_ops;
 #endif
 
+void board_reset (void)
+{
+    /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
+    au_writel(0x00000000, 0xAE00001C);
+}
+
 void __init board_setup(void)
 {
 	u32 pin_func;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/pb1500/irqmap.c linux-2.4.29-pre3/arch/mips/au1000/pb1500/irqmap.c
--- linux-2.4.28/arch/mips/au1000/pb1500/irqmap.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/pb1500/irqmap.c	2004-12-22 16:06:19.756294528 +0000
@@ -48,53 +48,37 @@
 #include <asm/au1000.h>
 
 au1xxx_irq_map_t au1xxx_irq_map[] = {
-	{ AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0},
-
-	{ AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0},
-
-	{ AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
 	{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
-
-	{ AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
-
-	{ AU1000_PCI_INTA, INTC_INT_LOW_LEVEL, 0 },
-	{ AU1000_PCI_INTB, INTC_INT_LOW_LEVEL, 0 },
-	{ AU1000_PCI_INTC, INTC_INT_LOW_LEVEL, 0 },
-	{ AU1000_PCI_INTD, INTC_INT_LOW_LEVEL, 0 },
 	{ AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
 	{ AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 },
 	{ AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 },
 	{ AU1500_GPIO_205, INTC_INT_LOW_LEVEL, 0 },
-	{ AU1500_GPIO_207, INTC_INT_LOW_LEVEL, 0 },
+};
 
-	{ AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_USB_DEV_REQ_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
-
-	/* Careful if you change match 2 request!
-	 * The interrupt handler is called directly
-	 * from the low level dispatch code.
+int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t);
+
+#ifdef CONFIG_PCI
+
+#define INTA AU1000_PCI_INTA
+#define INTB AU1000_PCI_INTB
+#define INTC AU1000_PCI_INTC
+#define INTD AU1000_PCI_INTD
+#define INTX 0xFF /* not valid */
+
+int __init
+au1xxx_pci_irqmap(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+	static char pci_irq_table[][4] =
+	/*
+	 *	PCI IDSEL/INTPIN->INTLINE
+	 *	A       B       C       D
 	 */
-	{ AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
+	{
+		{INTA, INTX, INTX, INTX},   /* IDSEL 12 - HPT370   */
+		{INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot */
+	};
+	const long min_idsel = 12, max_idsel = 13, irqs_per_slot = 4;
+	return PCI_IRQ_TABLE_LOOKUP;
 };
+#endif
 
-int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/pb1550/Makefile linux-2.4.29-pre3/arch/mips/au1000/pb1550/Makefile
--- linux-2.4.28/arch/mips/au1000/pb1550/Makefile	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/pb1550/Makefile	2004-12-22 16:06:05.738425568 +0000
@@ -10,10 +10,7 @@
 # unless it's something special (ie not a .c file).
 #
 
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
 
 O_TARGET := pb1550.o
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/pb1550/board_setup.c linux-2.4.29-pre3/arch/mips/au1000/pb1550/board_setup.c
--- linux-2.4.28/arch/mips/au1000/pb1550/board_setup.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/pb1550/board_setup.c	2004-12-22 16:07:21.012982096 +0000
@@ -44,24 +44,39 @@
 #include <asm/reboot.h>
 #include <asm/pgtable.h>
 #include <asm/au1000.h>
-#include <asm/db1x00.h>
+#include <asm/pb1550.h>
 
 extern struct rtc_ops no_rtc_ops;
 
-static BCSR * const bcsr = (BCSR *)0xB3000000;
+void board_reset (void)
+{
+    /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
+	au_writew(au_readw(0xAF00001C) & ~(1<<15), 0xAF00001C);
+}
 
 void __init board_setup(void)
 {
 	u32 pin_func;
 	rtc_ops = &no_rtc_ops;
 
-#ifdef CONFIG_AU1X00_USB_DEVICE
-	// 2nd USB port is USB device
-	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);
+	/* Enable PSC1 SYNC for AC97.  Normaly done in audio driver,
+	 * but it is board specific code, so put it here.
+	 */
+	pin_func = au_readl(SYS_PINFUNC);
+	au_sync();
+	pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
+	au_writel(pin_func, SYS_PINFUNC);
+
+	/* Do some more for PSC3 I2S audio.
+	*/
+	pin_func = au_readl(SYS_PINFUNC);
+	au_sync();
+	pin_func &= ~SYS_PF_PSC3_MASK;
+	pin_func |= SYS_PF_PSC3_I2S | SYS_PF_EX0;
 	au_writel(pin_func, SYS_PINFUNC);
-#endif
 
 	au_writel(0, (u32)bcsr|0x10); /* turn off pcmcia power */
+	au_sync();
 
-    printk("AMD Alchemy Pb1550 Board\n");
+	printk("AMD Alchemy Pb1550 Board\n");
 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/pb1550/init.c linux-2.4.29-pre3/arch/mips/au1000/pb1550/init.c
--- linux-2.4.28/arch/mips/au1000/pb1550/init.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/pb1550/init.c	2004-12-22 16:05:45.739465872 +0000
@@ -46,7 +46,7 @@ extern char *prom_getenv(char *envname);
 
 const char *get_system_type(void)
 {
-	return "AMD Alchemy PbAu1550";
+	return "AMD Alchemy Au1550/Pb1550";
 }
 
 int __init prom_init(int argc, char **argv, char **envp, int *prom_vec)
@@ -64,7 +64,7 @@ int __init prom_init(int argc, char **ar
 
 	memsize_str = prom_getenv("memsize");
 	if (!memsize_str) {
-		memsize = 0x04000000;
+		memsize = 0x08000000;
 	} else {
 		memsize = simple_strtol(memsize_str, NULL, 0);
 	}
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/pb1550/irqmap.c linux-2.4.29-pre3/arch/mips/au1000/pb1550/irqmap.c
--- linux-2.4.28/arch/mips/au1000/pb1550/irqmap.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/pb1550/irqmap.c	2004-12-22 16:07:31.915324688 +0000
@@ -48,46 +48,35 @@
 #include <asm/au1000.h>
 
 au1xxx_irq_map_t au1xxx_irq_map[] = {
-	{ AU1550_UART0_INT, 	INTC_INT_HIGH_LEVEL, 0},
-	{ AU1550_PCI_INTA, 		INTC_INT_LOW_LEVEL, 0 },
-	{ AU1550_PCI_INTB, 		INTC_INT_LOW_LEVEL, 0 },
-	{ AU1550_DDMA_INT, 		INTC_INT_HIGH_LEVEL, 0},
-	{ AU1550_CRYPTO_INT, 	INTC_INT_HIGH_LEVEL, 0},
-	{ AU1550_PCI_INTC, 		INTC_INT_LOW_LEVEL, 0 },
-	{ AU1550_PCI_INTD, 		INTC_INT_LOW_LEVEL, 0 },
-	{ AU1550_PCI_RST_INT, 	INTC_INT_LOW_LEVEL, 0 },
-	{ AU1550_UART1_INT, 	INTC_INT_HIGH_LEVEL, 0},
-	{ AU1550_UART3_INT, 	INTC_INT_HIGH_LEVEL, 0},
-	{ AU1550_PSC0_INT, 		INTC_INT_HIGH_LEVEL, 0},
-	{ AU1550_PSC1_INT, 		INTC_INT_HIGH_LEVEL, 0},
-	{ AU1550_PSC2_INT, 		INTC_INT_HIGH_LEVEL, 0},
-	{ AU1550_PSC3_INT, 		INTC_INT_HIGH_LEVEL, 0},
-	{ AU1550_TOY_INT, 		INTC_INT_RISE_EDGE, 0 },
-	{ AU1550_TOY_MATCH0_INT,INTC_INT_RISE_EDGE, 0 },
-	{ AU1550_TOY_MATCH1_INT,INTC_INT_RISE_EDGE, 0 },
-	/* Careful if you change match 2 request!
-	 * The interrupt handler is called directly
-	 * from the low level dispatch code.
-	 */
-	{ AU1550_TOY_MATCH2_INT,INTC_INT_RISE_EDGE, 0 },
-	{ AU1550_RTC_INT, 		INTC_INT_RISE_EDGE, 0 },
-	{ AU1550_RTC_MATCH0_INT,INTC_INT_RISE_EDGE, 0 },
-	{ AU1550_RTC_MATCH1_INT,INTC_INT_RISE_EDGE, 0 },
-	{ AU1550_RTC_MATCH2_INT,INTC_INT_RISE_EDGE, 0 },
-	{ AU1550_RTC_MATCH2_INT,INTC_INT_RISE_EDGE, 0 },
-	{ AU1550_NAND_INT, 		INTC_INT_RISE_EDGE, 0 },
-	{ AU1550_USB_DEV_REQ_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1550_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1550_USB_HOST_INT,  INTC_INT_LOW_LEVEL, 0 },
-	{ AU1550_MAC0_DMA_INT,  INTC_INT_HIGH_LEVEL, 0},
-	{ AU1550_MAC1_DMA_INT,  INTC_INT_HIGH_LEVEL, 0},
+	{ AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 },
+	{ AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 },
+};
+
+int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t);
 
 
+#ifdef CONFIG_PCI
+
+#define INTA AU1550_PCI_INTA
+#define INTB AU1550_PCI_INTB
+#define INTC AU1550_PCI_INTC
+#define INTD AU1550_PCI_INTD
+#define INTX 0xFF /* invalid */
+
+int __init
+au1xxx_pci_irqmap(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+	static char pci_irq_table[][4] =
 	/*
-	 *  Need to define platform dependant GPIO ints here
+	 *	PCI IDSEL/INTPIN->INTLINE
+	 *	A       B       C       D
 	 */
-	#warning PbAu1550 needs GPIO Interrupts defined
-
+    {
+		{INTB, INTC, INTD, INTA},   /* IDSEL 12 - PCI slot 2 (left)  */
+		{INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot 1 (right) */
+	};
+	const long min_idsel = 12, max_idsel = 13, irqs_per_slot = 4;
+	return PCI_IRQ_TABLE_LOOKUP;
 };
+#endif
 
-int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/xxs1500/Makefile linux-2.4.29-pre3/arch/mips/au1000/xxs1500/Makefile
--- linux-2.4.28/arch/mips/au1000/xxs1500/Makefile	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/xxs1500/Makefile	2004-12-22 16:06:15.408955424 +0000
@@ -10,10 +10,7 @@
 # unless it's something special (ie not a .c file).
 #
 
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
 
 O_TARGET := xxs1500.o
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/xxs1500/board_setup.c linux-2.4.29-pre3/arch/mips/au1000/xxs1500/board_setup.c
--- linux-2.4.28/arch/mips/au1000/xxs1500/board_setup.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/xxs1500/board_setup.c	2004-12-22 16:07:52.971123720 +0000
@@ -47,6 +47,12 @@
 
 extern struct rtc_ops no_rtc_ops;
 
+void board_reset (void)
+{
+	/* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
+	au_writel(0x00000000, 0xAE00001C);
+}
+
 void __init board_setup(void)
 {
 	u32 pin_func;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/au1000/xxs1500/irqmap.c linux-2.4.29-pre3/arch/mips/au1000/xxs1500/irqmap.c
--- linux-2.4.28/arch/mips/au1000/xxs1500/irqmap.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/au1000/xxs1500/irqmap.c	2004-12-22 16:06:05.109521176 +0000
@@ -48,29 +48,7 @@
 #include <asm/au1000.h>
 
 au1xxx_irq_map_t au1xxx_irq_map[] = {
-	{ AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0},
-
-	{ AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0},
-
-	{ AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
-	{ AU1000_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0},
 	{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
-
-	{ AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
-	{ AU1000_PCI_INTA, INTC_INT_LOW_LEVEL, 0 },
-	{ AU1000_PCI_INTB, INTC_INT_LOW_LEVEL, 0 },
-	{ AU1000_PCI_INTC, INTC_INT_LOW_LEVEL, 0 },
-	{ AU1000_PCI_INTD, INTC_INT_LOW_LEVEL, 0 },
 	{ AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
 	{ AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 },
 	{ AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 },
@@ -83,24 +61,31 @@ au1xxx_irq_map_t au1xxx_irq_map[] = {
 	{ AU1000_GPIO_3, INTC_INT_LOW_LEVEL, 0 },
 	{ AU1000_GPIO_4, INTC_INT_LOW_LEVEL, 0 }, /* CF interrupt */
 	{ AU1000_GPIO_5, INTC_INT_LOW_LEVEL, 0 },
-
-	{ AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_USB_DEV_REQ_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
-	{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
-
-	/* Careful if you change match 2 request!
-	 * The interrupt handler is called directly
-	 * from the low level dispatch code.
-	 */
-	{ AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
 };
 
 int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t);
+
+#ifdef CONFIG_PCI
+
+#define INTA AU1000_PCI_INTA
+#define INTB AU1000_PCI_INTB
+#define INTC AU1000_PCI_INTC
+#define INTD AU1000_PCI_INTD
+#define INTX 0xFF /* not valid */
+
+int __init
+au1xxx_pci_irqmap(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+	static char pci_irq_table[][4] =
+	/*
+	 *	PCI IDSEL/INTPIN->INTLINE
+	 *	A       B       C       D
+	 */
+	{
+		{INTA, INTX, INTX, INTX},   /* IDSEL 12 */
+		{INTA, INTB, INTC, INTD},   /* IDSEL 13 - PCI slot */
+	};
+	const long min_idsel = 12, max_idsel = 13, irqs_per_slot = 4;
+	return PCI_IRQ_TABLE_LOOKUP;
+};
+#endif
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/boot/Makefile linux-2.4.29-pre3/arch/mips/boot/Makefile
--- linux-2.4.28/arch/mips/boot/Makefile	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/boot/Makefile	2004-12-22 16:07:20.144114184 +0000
@@ -4,6 +4,7 @@
 # for more details.
 #
 # Copyright (C) 1995, 1998, 2001 by Ralf Baechle
+# Copyright (C) 2004  Maciej W. Rozycki
 #
 
 USE_STANDARD_AS_RULE := true
@@ -21,19 +22,23 @@ endif
 # Drop some uninteresting sections in the kernel.
 # This is only relevant for ELF kernels but doesn't hurt a.out
 #
-drop-sections	= .reginfo .mdebug
+drop-sections	= .reginfo .mdebug .comment .note .pdr .options .MIPS.options
 strip-flags	= $(addprefix --remove-section=,$(drop-sections))
 
-all: vmlinux.ecoff vmlinux.srec addinitrd
+VMLINUX = $(TOPDIR)/vmlinux
 
-vmlinux.ecoff:	$(CONFIGURE) elf2ecoff $(TOPDIR)/vmlinux
-	./elf2ecoff $(TOPDIR)/vmlinux vmlinux.ecoff $(E2EFLAGS)
+all:
+
+boot: vmlinux.ecoff vmlinux.srec addinitrd
+
+vmlinux.ecoff:	$(CONFIGURE) elf2ecoff $(VMLINUX)
+	./elf2ecoff $(VMLINUX) vmlinux.ecoff $(E2EFLAGS)
 
 elf2ecoff: elf2ecoff.c
 	$(HOSTCC) -o $@ $^
 
-vmlinux.srec: $(CONFIGURE) $(TOPDIR)/vmlinux
-	$(OBJCOPY) -S -O srec $(strip-flags) $(TOPDIR)/vmlinux vmlinux.srec
+vmlinux.srec: $(CONFIGURE) $(VMLINUX)
+	$(OBJCOPY) -S -O srec $(strip-flags) $(VMLINUX) vmlinux.srec
 
 addinitrd: addinitrd.c
 	$(HOSTCC) -o $@ $^
@@ -42,15 +47,10 @@ addinitrd: addinitrd.c
 dep:
 
 clean:
-	rm -f vmlinux.ecoff
-	rm -f vmlinux.srec
-	rm -f zImage zImage.tmp
+	rm -f vmlinux.ecoff vmlinux.srec
 
 mrproper:
-	rm -f vmlinux.ecoff
-	rm -f vmlinux.srec
-	rm -f addinitrd
-	rm -f elf2ecoff
+	rm -f vmlinux.ecoff vmlinux.srec addinitrd elf2ecoff
 
 dummy:
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/boot/addinitrd.c linux-2.4.29-pre3/arch/mips/boot/addinitrd.c
--- linux-2.4.28/arch/mips/boot/addinitrd.c	2002-11-28 23:53:09.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/boot/addinitrd.c	2004-12-22 16:07:14.298002928 +0000
@@ -2,6 +2,8 @@
  * addinitrd - program to add a initrd image to an ecoff kernel
  *
  * (C) 1999 Thomas Bogendoerfer
+ * minor modifications, cleanup: Guido Guenther <agx@sigxcpu.org>
+ * further cleanup: Maciej W. Rozycki
  */
 
 #include <sys/types.h>
@@ -54,7 +56,7 @@ int main (int argc, char *argv[])
 		exit (1);
 	}
 
-	if ((fd_vmlinux = open (argv[1],O_RDWR)) < 0)
+	if ((fd_vmlinux = open (argv[1],O_RDONLY)) < 0)
 		 die ("open vmlinux");
 	if (read (fd_vmlinux, &efile, sizeof efile) != sizeof efile)
 		die ("read file header");
@@ -78,6 +80,11 @@ int main (int argc, char *argv[])
 			swab = 1;
 	}
 
+	/* make sure we have an empty data segment for the initrd */
+	if (eaout.dsize || esecs[1].s_size) {
+		fprintf (stderr, "Data segment not empty. Giving up!\n");
+		exit (1);
+	}
 	if ((fd_initrd = open (argv[2], O_RDONLY)) < 0)
 		die ("open initrd");
 	if (fstat (fd_initrd, &st) < 0)
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/config-shared.in linux-2.4.29-pre3/arch/mips/config-shared.in
--- linux-2.4.28/arch/mips/config-shared.in	2004-12-22 16:17:15.648583744 +0000
+++ linux-2.4.29-pre3/arch/mips/config-shared.in	2004-12-22 16:06:49.187820256 +0000
@@ -25,10 +25,8 @@ dep_bool 'Support for Alchemy Mirage boa
 dep_bool 'Support for Alchemy Db1000 board' CONFIG_MIPS_DB1000 $CONFIG_MIPS32
 dep_bool 'Support for Alchemy Db1100 board' CONFIG_MIPS_DB1100 $CONFIG_MIPS32
 dep_bool 'Support for Alchemy Db1500 board' CONFIG_MIPS_DB1500 $CONFIG_MIPS32
+dep_bool 'Support for Alchemy Db1550 board' CONFIG_MIPS_DB1550 $CONFIG_MIPS32
 dep_bool 'Support for Alchemy PB1000 board' CONFIG_MIPS_PB1000 $CONFIG_MIPS32
-if [ "$CONFIG_MIPS_PB1000" = "y" ]; then
-   bool '  Support for PCI AUTO Config' CONFIG_PCI_AUTO
-fi
 dep_bool 'Support for Alchemy PB1100 board' CONFIG_MIPS_PB1100 $CONFIG_MIPS32
 dep_bool 'Support for Alchemy PB1500 board' CONFIG_MIPS_PB1500 $CONFIG_MIPS32
 dep_bool 'Support for Alchemy Hydrogen3 board' CONFIG_MIPS_HYDROGEN3 $CONFIG_MIPS32
@@ -39,10 +37,8 @@ dep_bool 'Support for Cogent CSB250 boar
 dep_bool 'Support for BAGET MIPS series (EXPERIMENTAL)' CONFIG_BAGET_MIPS $CONFIG_MIPS32 $CONFIG_EXPERIMENTAL
 bool 'Support for CASIO CASSIOPEIA E-10/15/55/65' CONFIG_CASIO_E55
 dep_bool 'Support for Cobalt Server (EXPERIMENTAL)' CONFIG_MIPS_COBALT $CONFIG_EXPERIMENTAL
-if [ "$CONFIG_MIPS32" = "y" ]; then
+if [ "$CONFIG_MIPS32" = "y" -o "$CONFIG_EXPERIMENTAL" = "y" ]; then
    bool 'Support for DECstations' CONFIG_DECSTATION
-else
-   dep_bool 'Support for DECstations (EXPERIMENTAL)' CONFIG_DECSTATION $CONFIG_EXPERIMENTAL
 fi
 dep_bool 'Support for Galileo EV64120 Evaluation board (EXPERIMENTAL)' CONFIG_MIPS_EV64120 $CONFIG_EXPERIMENTAL
 if [ "$CONFIG_MIPS_EV64120" = "y" ]; then
@@ -64,6 +60,9 @@ if [ "$CONFIG_LASAT" = "y" ]; then
    tristate '  PICVUE LCD display driver' CONFIG_PICVUE
    dep_tristate '   PICVUE LCD display driver /proc interface' CONFIG_PICVUE_PROC $CONFIG_PICVUE
    bool '  DS1603 RTC driver' CONFIG_DS1603
+   if [ "$CONFIG_DS1603" = "y" ]; then
+      define_bool CONFIG_MIPS_RTC y
+   fi
    bool '  LASAT sysctl interface' CONFIG_LASAT_SYSCTL
 fi
 bool 'Support for ITE 8172G board' CONFIG_MIPS_ITE8172
@@ -78,7 +77,9 @@ bool 'Support for Momentum Ocelot board'
 bool 'Support for Momentum Ocelot-G board' CONFIG_MOMENCO_OCELOT_G
 bool 'Support for Momentum Ocelot-C and -CS boards' CONFIG_MOMENCO_OCELOT_C
 bool 'Support for Momentum Jaguar-ATX boards' CONFIG_MOMENCO_JAGUAR_ATX
-bool 'Support PMC-Sierra Yosemite board' CONFIG_PMC_YOSEMITE
+bool 'Support for PMC-Sierra Big Sur board' CONFIG_PMC_BIG_SUR
+bool 'Support for PMC-Sierra Stretch board' CONFIG_PMC_STRETCH
+bool 'Support for PMC-Sierra Yosemite board' CONFIG_PMC_YOSEMITE
 if [ "$CONFIG_PMC_YOSEMITE" = "y" ]; then
    bool '  Hypertransport Support for PMC-Sierra Yosemite'  CONFIG_HYPERTRANSPORT
 fi
@@ -124,14 +125,14 @@ if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ]
            BCM91250C2-LittleSur CONFIG_SIBYTE_LITTLESUR \
            BCM91120C-CRhine     CONFIG_SIBYTE_CRHINE \
            BCM91125C-CRhone     CONFIG_SIBYTE_CRHONE \
-           Other                CONFIG_SIBYTE_UNKNOWN" CONFIG_SIBYTE_SWARM
+           Other                CONFIG_SIBYTE_UNKNOWN" BCM91250A-SWARM
 
    if [ "$CONFIG_SIBYTE_UNKNOWN" = "y" ]; then
       choice '   BCM1xxx SOC Type' \
           "BCM1250     CONFIG_SIBYTE_SB1250 \
            BCM1120     CONFIG_SIBYTE_BCM1120 \
            BCM1125     CONFIG_SIBYTE_BCM1125 \
-           BCM1125H    CONFIG_SIBYTE_BCM1125H" CONFIG_SIBYTE_SB1250
+           BCM1125H    CONFIG_SIBYTE_BCM1125H" BCM1250
       unset CONFIG_SIBYTE_BOARD
    else
       define_bool CONFIG_SIBYTE_BOARD y
@@ -191,19 +192,6 @@ if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ]
    bool '   Support for SB1/SOC profiling - SB1/SCD perf counters' CONFIG_SIBYTE_SB1250_PROF
    bool '   Support for ZBbus profiling' CONFIG_SIBYTE_TBPROF
 
-   if [ "$CONFIG_SIBYTE_SB1250" = "y" -o \
-        "$CONFIG_SIBYTE_BCM1125" = "y" -o \
-        "$CONFIG_SIBYTE_BCM1125H" = "y" ]; then
-      bool '   Support for BCM1250/BCM1125 onchip PCI controller' CONFIG_PCI
-   fi
-
-   if [ "$CONFIG_SIBYTE_SB1250" = "y" -o \
-        "$CONFIG_SIBYTE_BCM1125H" = "y" ]; then
-      if [ "$CONFIG_PCI" = "y" ]; then
-         define_bool CONFIG_SIBYTE_HAS_LDT y
-      fi
-   fi
-
    if [ "$CONFIG_SIBYTE_SWARM" = "y" -o \
         "$CONFIG_SIBYTE_LITTLESUR" = "y" -o \
         "$CONFIG_SIBYTE_PTSWARM" = "y" -o \
@@ -215,6 +203,7 @@ if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ]
         "$CONFIG_SIBYTE_STANDALONE" != "y" ]; then
       define_bool CONFIG_SMP_CAPABLE y
    fi
+   define_bool CONFIG_MIPS_RTC y
 fi
 bool 'Support for SNI RM200 PCI' CONFIG_SNI_RM200_PCI
 bool 'Support for TANBAC TB0226 (Mbase)' CONFIG_TANBAC_TB0226
@@ -246,11 +235,9 @@ if [ "$CONFIG_ACER_PICA_61" = "y" ]; the
    define_bool CONFIG_MIPS_JAZZ y
    define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_PC_KEYB y
-   define_bool CONFIG_OLD_TIME_C y
 fi
 if [ "$CONFIG_CASIO_E55" = "y" ]; then
    define_bool CONFIG_IRQ_CPU y
-   define_bool CONFIG_NEW_TIME_C y
    define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_ISA y
    define_bool CONFIG_DUMMY_KEYB y
@@ -259,29 +246,18 @@ fi
 if [ "$CONFIG_MIPS_MIRAGE" = "y" ]; then
    define_bool CONFIG_SOC_AU1X00 y
    define_bool CONFIG_SOC_AU1500 y
-   define_bool CONFIG_NEW_TIME_C y
    define_bool CONFIG_PC_KEYB y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_NEW_PCI y
-   define_bool CONFIG_PCI_AUTO y
    define_bool CONFIG_NONCOHERENT_IO y
 fi
 if [ "$CONFIG_MIPS_BOSPORUS" = "y" ]; then
    define_bool CONFIG_SOC_AU1X00 y
    define_bool CONFIG_SOC_AU1500 y
-   define_bool CONFIG_NEW_TIME_C y
    define_bool CONFIG_PC_KEYB y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_NEW_PCI y
-   define_bool CONFIG_PCI_AUTO y
    define_bool CONFIG_NONCOHERENT_IO y
 fi
 if [ "$CONFIG_MIPS_PB1000" = "y" ]; then
    define_bool CONFIG_SOC_AU1X00 y
    define_bool CONFIG_SOC_AU1000 y
-   define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_NEW_PCI y
    define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_PC_KEYB y
    define_bool CONFIG_SWAP_IO_SPACE_W y
@@ -290,10 +266,6 @@ fi
 if [ "$CONFIG_MIPS_PB1100" = "y" ]; then
    define_bool CONFIG_SOC_AU1X00 y
    define_bool CONFIG_SOC_AU1100 y
-   define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_PCI_AUTO n
-   define_bool CONFIG_NEW_PCI y
    define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_PC_KEYB y
    define_bool CONFIG_SWAP_IO_SPACE_W y
@@ -302,21 +274,12 @@ fi
 if [ "$CONFIG_MIPS_PB1500" = "y" ]; then
    define_bool CONFIG_SOC_AU1X00 y
    define_bool CONFIG_SOC_AU1500 y
-   define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_NEW_PCI y
-   define_bool CONFIG_PCI_AUTO y
    define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_PC_KEYB y
 fi
 if [ "$CONFIG_MIPS_DB1000" = "y" ]; then
    define_bool CONFIG_SOC_AU1X00 y
    define_bool CONFIG_SOC_AU1000 y
-   define_bool CONFIG_NEW_TIME_C y
-   # CONFIG_PCI needed for USB
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_NEW_PCI y
-   define_bool CONFIG_PCI_AUTO n
    define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_PC_KEYB y
    define_bool CONFIG_SWAP_IO_SPACE y
@@ -324,19 +287,18 @@ fi
 if [ "$CONFIG_MIPS_DB1500" = "y" ]; then
    define_bool CONFIG_SOC_AU1X00 y
    define_bool CONFIG_SOC_AU1500 y
-   define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_NEW_PCI y
-   define_bool CONFIG_PCI_AUTO y
+   define_bool CONFIG_NONCOHERENT_IO y
+   define_bool CONFIG_PC_KEYB y
+fi
+if [ "$CONFIG_MIPS_DB1550" = "y" ]; then
+   define_bool CONFIG_SOC_AU1X00 y
+   define_bool CONFIG_SOC_AU1550 y
    define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_PC_KEYB y
 fi
 if [ "$CONFIG_MIPS_DB1100" = "y" ]; then
    define_bool CONFIG_SOC_AU1X00 y
    define_bool CONFIG_SOC_AU1100 y
-   define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_NEW_PCI y
    define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_PC_KEYB y
    define_bool CONFIG_SWAP_IO_SPACE y
@@ -344,9 +306,6 @@ fi
 if [ "$CONFIG_MIPS_HYDROGEN3" = "y" ]; then
    define_bool CONFIG_SOC_AU1X00 y
    define_bool CONFIG_SOC_AU1100 y
-   define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_NEW_PCI y
    define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_PC_KEYB y
    define_bool CONFIG_SWAP_IO_SPACE y
@@ -354,39 +313,23 @@ fi
 if [ "$CONFIG_MIPS_XXS1500" = "y" ]; then
    define_bool CONFIG_SOC_AU1X00 y
    define_bool CONFIG_SOC_AU1500 y
-   define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_NEW_PCI y
-   define_bool CONFIG_PCI_AUTO y
    define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_PC_KEYB y
 fi
 if [ "$CONFIG_MIPS_MTX1" = "y" ]; then
    define_bool CONFIG_SOC_AU1X00 y
    define_bool CONFIG_SOC_AU1500 y
-   define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_NEW_PCI y
-   define_bool CONFIG_PCI_AUTO y
    define_bool CONFIG_NONCOHERENT_IO y
 fi
 if [ "$CONFIG_COGENT_CSB250" = "y" ]; then
    define_bool CONFIG_SOC_AU1X00 y
    define_bool CONFIG_SOC_AU1500 y
-   define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_NEW_PCI y
-   define_bool CONFIG_PCI_AUTO y
    define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_PC_KEYB y
 fi
 if [ "$CONFIG_MIPS_PB1550" = "y" ]; then
    define_bool CONFIG_SOC_AU1X00 y
    define_bool CONFIG_SOC_AU1550 y
-   define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_NEW_PCI y
-   define_bool CONFIG_PCI_AUTO y
    define_bool CONFIG_NONCOHERENT_IO n
    define_bool CONFIG_PC_KEYB y
 fi
@@ -394,53 +337,37 @@ if [ "$CONFIG_MIPS_COBALT" = "y" ]; then
    define_bool CONFIG_BOOT_ELF32 y
    define_bool CONFIG_COBALT_LCD y
    define_bool CONFIG_I8259 y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_NEW_TIME_C y
    define_bool CONFIG_NONCOHERENT_IO y
 fi
 if [ "$CONFIG_DECSTATION" = "y" ]; then
+   define_bool CONFIG_EARLY_PRINTK y
    define_bool CONFIG_BOOT_ELF32 y
    define_bool CONFIG_IRQ_CPU y
    define_int CONFIG_L1_CACHE_SHIFT 4
-   define_bool CONFIG_NEW_TIME_C y
    define_bool CONFIG_NONCOHERENT_IO y
 fi
 if [ "$CONFIG_MIPS_EV64120" = "y" ]; then
-   define_bool CONFIG_PCI y
    define_bool CONFIG_MIPS_GT64120 y
    define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_OLD_TIME_C y
 fi
 if [ "$CONFIG_MIPS_EV96100" = "y" ]; then
-   define_bool CONFIG_PCI y
    define_bool CONFIG_MIPS_GT64120 y
    define_bool CONFIG_MIPS_GT96100 y
-   define_bool CONFIG_NEW_PCI y
    define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_PCI_AUTO y
    define_bool CONFIG_SWAP_IO_SPACE_W y
    define_bool CONFIG_SWAP_IO_SPACE_L y
 fi
 if [ "$CONFIG_MIPS_IVR" = "y" ]; then
-   define_bool CONFIG_PCI y
    define_bool CONFIG_PC_KEYB y
-   define_bool CONFIG_NEW_PCI y
    define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_PCI_AUTO y
    define_bool CONFIG_IT8172_CIR y
-   define_bool CONFIG_NEW_TIME_C y
 fi
 if [ "$CONFIG_HP_LASERJET" = "y" ]; then
    define_bool CONFIG_IRQ_CPU y
-   define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_NEW_PCI y
    define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_PCI y
-   #not yet define_bool CONFIG_PCI_AUTO y
 fi
 if [ "$CONFIG_IBM_WORKPAD" = "y" ]; then
    define_bool CONFIG_IRQ_CPU y
-   define_bool CONFIG_NEW_TIME_C y
    define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_ISA y
    define_bool CONFIG_SCSI n
@@ -448,21 +375,15 @@ fi
 if [ "$CONFIG_LASAT" = "y" ]; then
    define_bool CONFIG_BOARD_SCACHE y
    define_bool CONFIG_R5000_CPU_SCACHE y
-   define_bool CONFIG_PCI y
    define_bool CONFIG_MIPS_GT64120 y
    define_bool CONFIG_MIPS_NILE4 y
    define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_NEW_TIME_C y
 fi
 if [ "$CONFIG_MIPS_ITE8172" = "y" ]; then
-   define_bool CONFIG_PCI y
    define_bool CONFIG_IT8712 y
    define_bool CONFIG_PC_KEYB y
-   define_bool CONFIG_NEW_PCI y
    define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_PCI_AUTO y
    define_bool CONFIG_IT8172_CIR y
-   define_bool CONFIG_NEW_TIME_C y
 fi
 if [ "$CONFIG_MIPS_ATLAS" = "y" ]; then
    define_bool CONFIG_BOOT_ELF32 y
@@ -470,9 +391,7 @@ if [ "$CONFIG_MIPS_ATLAS" = "y" ]; then
    define_bool CONFIG_MIPS_BONITO64 y
    define_bool CONFIG_MIPS_GT64120 y
    define_bool CONFIG_MIPS_MSC y
-   define_bool CONFIG_NEW_TIME_C y
    define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_PCI y
    define_bool CONFIG_SWAP_IO_SPACE_W y
    define_bool CONFIG_SWAP_IO_SPACE_L y
 fi
@@ -486,7 +405,6 @@ if [ "$CONFIG_MIPS_MAGNUM_4000" = "y" -o
    define_bool CONFIG_MIPS_JAZZ y
    define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_PC_KEYB y
-   define_bool CONFIG_OLD_TIME_C y
 fi
 if [ "$CONFIG_MIPS_MALTA" = "y" ]; then
    define_bool CONFIG_BOOT_ELF32 y
@@ -496,59 +414,58 @@ if [ "$CONFIG_MIPS_MALTA" = "y" ]; then
    define_bool CONFIG_MIPS_GT64120 y
    define_bool CONFIG_MIPS_MSC y
    define_int CONFIG_L1_CACHE_SHIFT 5
-   define_bool CONFIG_NEW_TIME_C y
    define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_SWAP_IO_SPACE_W y
    define_bool CONFIG_SWAP_IO_SPACE_L y
    define_bool CONFIG_PC_KEYB y
-   define_bool CONFIG_PCI y
 fi
 if [ "$CONFIG_MIPS_SEAD" = "y" ]; then
    define_bool CONFIG_BOOT_ELF32 y
    define_int CONFIG_L1_CACHE_SHIFT 5
-   define_bool CONFIG_NEW_TIME_C y
    define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_PCI n
 fi
 if [ "$CONFIG_MOMENCO_OCELOT" = "y" ]; then
-   define_bool CONFIG_PCI y
    define_bool CONFIG_SYSCLK_100 y
    define_bool CONFIG_SWAP_IO_SPACE_W y
    define_bool CONFIG_SWAP_IO_SPACE_L y
    define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_OLD_TIME_C y
 fi
 if [ "$CONFIG_MOMENCO_OCELOT_G" = "y" ]; then
-   define_bool CONFIG_PCI y
+   define_bool CONFIG_IRQ_CPU y
+   define_bool CONFIG_IRQ_CPU_RM7K y
+   define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_SYSCLK_100 y
    define_bool CONFIG_SWAP_IO_SPACE_W y
    define_bool CONFIG_SWAP_IO_SPACE_L y
-   define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_OLD_TIME_C y
 fi
 if [ "$CONFIG_MOMENCO_OCELOT_C" = "y" ]; then
-   define_bool CONFIG_PCI y
    define_bool CONFIG_SWAP_IO_SPACE y
    define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_NEW_TIME_C y
+   define_bool CONFIG_BOOT_ELF32 y
+fi
+if [ "$CONFIG_PMC_BIG_SUR" = "y" ]; then
    define_bool CONFIG_BOOT_ELF32 y
 fi
 if [ "$CONFIG_MOMENCO_JAGUAR_ATX" = "y" ]; then
-   define_bool CONFIG_PCI y
    define_bool CONFIG_SWAP_IO_SPACE y
    define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_NEW_TIME_C y
    define_bool CONFIG_BOOT_ELF32 y
 fi
 
-if [ "$CONFIG_PMC_YOSEMITE" = "y" ]; then
+if [ "$CONFIG_PMC_STRETCH" = "y" ]; then
+   define_bool CONFIG_SWAP_IO_SPACE_W y
+   define_bool CONFIG_SWAP_IO_SPACE_L y
    define_bool CONFIG_PCI y
+   define_bool CONFIG_BOOT_ELF32 y
+   define_bool CONFIG_NONCOHERENT_IO y
+fi
+
+if [ "$CONFIG_PMC_YOSEMITE" = "y" ]; then
    define_bool CONFIG_SWAP_IO_SPACE y
    define_bool CONFIG_SWAP_IO_SPACE_W y
    define_bool CONFIG_SWAP_IO_SPACE_L y
    define_bool CONFIG_BOOT_ELF32 y
    define_bool CONFIG_HIGHMEM y
-   define_bool CONFIG_NEW_TIME_C y
    define_bool CONFIG_NONCOHERENT_IO y
 fi
 
@@ -557,55 +474,37 @@ if [ "$CONFIG_DDB5074" = "y" ]; then
    define_bool CONFIG_I8259 y
    define_bool CONFIG_ISA y
    define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_PCI y
    define_bool CONFIG_PC_KEYB y
-   define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_PCI_AUTO y
    define_bool CONFIG_IRQ_CPU y
-   define_bool CONFIG_NEW_PCI y
 fi
 if [ "$CONFIG_DDB5476"  = "y" ]; then
    define_bool CONFIG_ISA y
-   define_bool CONFIG_PCI y
    define_bool CONFIG_PC_KEYB y
    define_bool CONFIG_IRQ_CPU y
    define_bool CONFIG_I8259 y
    define_bool CONFIG_HAVE_STD_PC_SERIAL_PORT y
-   define_bool CONFIG_NEW_PCI y
-   define_bool CONFIG_PCI_AUTO y
-   define_bool CONFIG_NEW_TIME_C y
    define_bool CONFIG_NONCOHERENT_IO y
 fi
 if [ "$CONFIG_DDB5477" = "y" ]; then
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_NEW_TIME_C y
    define_bool CONFIG_IRQ_CPU y
-   define_bool CONFIG_NEW_PCI y
    define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_PCI_AUTO y
    define_bool CONFIG_PC_KEYB y
    define_bool CONFIG_I8259 y
 fi
 if [ "$CONFIG_NEC_OSPREY" = "y" ]; then
    define_bool CONFIG_VR4181 y
    define_bool CONFIG_IRQ_CPU y
-   define_bool CONFIG_NEW_TIME_C y
    define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_DUMMY_KEYB y
    define_bool CONFIG_SCSI n
 fi
 if [ "$CONFIG_NEC_EAGLE" = "y" ]; then
    define_bool CONFIG_IRQ_CPU y
-   define_bool CONFIG_NEW_TIME_C y
    define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_NEW_PCI y
-   define_bool CONFIG_PCI_AUTO y
    define_bool CONFIG_DUMMY_KEYB y
    define_bool CONFIG_SCSI n
 fi
 if [ "$CONFIG_NINO" = "y" ]; then
-   define_bool CONFIG_NEW_TIME_C y
    define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_PC_KEYB y
 fi
@@ -618,7 +517,6 @@ if [ "$CONFIG_SGI_IP22" = "y" ]; then
    define_bool CONFIG_SWAP_IO_SPACE_L y
    define_bool CONFIG_IRQ_CPU y
    define_int CONFIG_L1_CACHE_SHIFT 5
-   define_bool CONFIG_NEW_TIME_C y
    define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_PC_KEYB y
 fi
@@ -627,12 +525,9 @@ if [ "$CONFIG_SGI_IP27" = "y" ]; then
    define_bool CONFIG_ARC64 y
    define_int CONFIG_L1_CACHE_SHIFT 7
    #define_bool CONFIG_MAPPED_PCI_IO y
-   define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_PCI y
    define_bool CONFIG_QL_ISP_A64 y
 fi
 if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ]; then
-   define_bool CONFIG_NEW_TIME_C y
    define_bool CONFIG_DUMMY_KEYB y
    define_bool CONFIG_SWAP_IO_SPACE_W y
    define_bool CONFIG_SWAP_IO_SPACE_L y
@@ -645,46 +540,28 @@ if [ "$CONFIG_SNI_RM200_PCI" = "y" ]; th
    define_bool CONFIG_I8259 y
    define_bool CONFIG_ISA y
    define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_OLD_TIME_C y
    define_bool CONFIG_PC_KEYB y
-   define_bool CONFIG_PCI y
 fi
 if [ "$CONFIG_TANBAC_TB0226" = "y" ]; then
    define_bool CONFIG_IRQ_CPU y
-   define_bool CONFIG_NEW_TIME_C y
    define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_NEW_PCI y
-   define_bool CONFIG_PCI_AUTO y
    define_bool CONFIG_DUMMY_KEYB y
    define_bool CONFIG_SERIAL_MANY_PORTS y
 fi
 if [ "$CONFIG_TANBAC_TB0229" = "y" ]; then
    define_bool CONFIG_IRQ_CPU y
-   define_bool CONFIG_NEW_TIME_C y
    define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_NEW_PCI y
-   define_bool CONFIG_PCI_AUTO y
    define_bool CONFIG_DUMMY_KEYB y
    define_bool CONFIG_SERIAL_MANY_PORTS y
 fi
 if [ "$CONFIG_TOSHIBA_JMR3927" = "y" ]; then
    define_bool CONFIG_TOSHIBA_BOARDS y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_NEW_PCI y
-   define_bool CONFIG_PCI_AUTO y
-   define_bool CONFIG_NEW_TIME_C y
    define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_SWAP_IO_SPACE_W y
    define_bool CONFIG_SWAP_IO_SPACE_L y
    define_bool CONFIG_PC_KEYB y
 fi
 if [ "$CONFIG_TOSHIBA_RBTX4927" = "y" ]; then
-   define_bool CONFIG_NEW_TIME_C y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_NEW_PCI y
-   define_bool CONFIG_PCI_AUTO y
    define_bool CONFIG_SWAP_IO_SPACE_W y
    define_bool CONFIG_SWAP_IO_SPACE_L y
    define_bool CONFIG_ISA y
@@ -692,21 +569,12 @@ if [ "$CONFIG_TOSHIBA_RBTX4927" = "y" ];
 fi
 if [ "$CONFIG_VICTOR_MPC30X" = "y" ]; then
    define_bool CONFIG_IRQ_CPU y
-   define_bool CONFIG_NEW_TIME_C y
    define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_NEW_PCI y
-   define_bool CONFIG_PCI_AUTO y
-   define_bool CONFIG_DUMMY_KEYB y
    define_bool CONFIG_SCSI n
 fi
 if [ "$CONFIG_ZAO_CAPCELLA" = "y" ]; then
    define_bool CONFIG_IRQ_CPU y
-   define_bool CONFIG_NEW_TIME_C y
    define_bool CONFIG_NONCOHERENT_IO y
-   define_bool CONFIG_PCI y
-   define_bool CONFIG_NEW_PCI y
-   define_bool CONFIG_PCI_AUTO y
    define_bool CONFIG_DUMMY_KEYB y
    define_bool CONFIG_SCSI n
 fi
@@ -752,12 +620,7 @@ if [ "$CONFIG_SMP_CAPABLE" = "y" ]; then
    bool '  Multi-Processing support' CONFIG_SMP
 fi
  
-if [ "$CONFIG_CPU_MIPS32" = "y" ]; then
-   define_bool CONFIG_CPU_HAS_PREFETCH y
-   bool '  Support for Virtual Tagged I-cache' CONFIG_VTAG_ICACHE
-fi
-
-if [ "$CONFIG_CPU_MIPS64" = "y" ]; then
+if [ "$CONFIG_CPU_MIPS32" = "y" -o "$CONFIG_CPU_MIPS64" = "y" ]; then
    define_bool CONFIG_CPU_HAS_PREFETCH y
    bool '  Support for Virtual Tagged I-cache' CONFIG_VTAG_ICACHE
 fi
@@ -889,6 +752,8 @@ else
    fi
 fi
 
+dep_bool 'Use 64-bit ELF format for building' CONFIG_BUILD_ELF64 $CONFIG_MIPS64
+
 if [ "$CONFIG_CPU_LITTLE_ENDIAN" = "n" ]; then
    bool 'Include IRIX binary compatibility' CONFIG_BINFMT_IRIX
 fi
@@ -903,15 +768,51 @@ fi
 
 bool 'Networking support' CONFIG_NET
 
+if [ "$CONFIG_ACER_PICA_61" = "y" -o \
+     "$CONFIG_CASIO_E55" = "y" -o \
+     "$CONFIG_DECSTATION" = "y" -o \
+     "$CONFIG_IBM_WORKPAD" = "y" -o \
+     "$CONFIG_MIPS_MAGNUM_4000" = "y" -o \
+     "$CONFIG_MIPS_SEAD" = "y" -o \
+     "$CONFIG_NINO" = "y" -o \
+     "$CONFIG_OLIVETTI_M700" = "y" -o \
+     "$CONFIG_SGI_IP22" = "y" ]; then
+   define_bool CONFIG_PCI n
+else
+   bool 'PCI bus support' CONFIG_PCI
+   dep_bool '    New PCI bus code' CONFIG_PCI_NEW $CONFIG_PCI
+   if [ "$CONFIG_HP_LASERJET" = "y" -o \
+        "$CONFIG_LASAT" = "y" -o \
+        "$CONFIG_MIPS_ATLAS" = "y" -o \
+        "$CONFIG_MIPS_COBALT" = "y" -o \
+        "$CONFIG_MIPS_DB1000" = "y" -o \
+        "$CONFIG_MIPS_DB1100" = "y" -o \
+        "$CONFIG_MIPS_EV64120" = "y" -o \
+        "$CONFIG_MIPS_HYDROGEN3" = "y" -o \
+        "$CONFIG_MIPS_MALTA" = "y" -o \
+        "$CONFIG_MIPS_PB1100" = "y" -o \
+        "$CONFIG_MOMENCO_OCELOT" = "y" -o \
+        "$CONFIG_NEC_OSPREY" = "y" -o \
+        "$CONFIG_PMC_YOSEMITE" = "y" -o \
+        "$CONFIG_SIBYTE_SWARM" = "y" -o \
+	"$CONFIG_SNI_RM200_PCI" = "y" ]; then
+      define_bool CONFIG_PCI_AUTO n
+   else
+      define_bool CONFIG_PCI_AUTO y
+   fi
+fi
+if [ "$CONFIG_SIBYTE_SB1250" = "y" -o \
+     "$CONFIG_SIBYTE_BCM1125H" = "y" ]; then
+   if [ "$CONFIG_PCI" = "y" ]; then
+      define_bool CONFIG_SIBYTE_HAS_LDT y
+   fi
+fi
+
 if [ "$CONFIG_SGI_IP22" = "y" -o "$CONFIG_MIPS_MAGNUM_4000" = "y" -o \
      "$CONFIG_OLIVETTI_M700" = "y" -o "$CONFIG_SNI_RM200_PCI" = "y" ]; then
    bool 'EISA bus support' CONFIG_EISA
 fi
 
-if [ "$CONFIG_PCI" != "y" ]; then
-   define_bool CONFIG_PCI n
-fi
-
 source drivers/pci/Config.in
 
 if [ "$CONFIG_EISA" = "y" -a "$CONFIG_ISA" != "y" ]; then
@@ -957,6 +858,11 @@ fi
 tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
 bool 'Select task to kill on out of memory condition' CONFIG_OOM_KILLER
 
+bool 'Default bootloader kernel arguments' CONFIG_CMDLINE_BOOL
+if [ "$CONFIG_CMDLINE_BOOL" = "y" ] ; then
+  string 'Initial kernel command string' CONFIG_CMDLINE ""
+fi
+
 if [ "$CONFIG_SOC_AU1X00" = "y" ]; then
    bool 'Power Management support' CONFIG_PM
 fi
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/dec/ecc-berr.c linux-2.4.29-pre3/arch/mips/dec/ecc-berr.c
--- linux-2.4.28/arch/mips/dec/ecc-berr.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/dec/ecc-berr.c	2004-12-22 16:06:45.464386304 +0000
@@ -74,7 +74,7 @@ static int dec_ecc_be_backend(struct pt_
 
 	if (!(erraddr & KN0X_EAR_VALID)) {
 		/* No idea what happened. */
-		printk(KERN_ALERT "Unindentified bus error %s.\n", kind);
+		printk(KERN_ALERT "Unidentified bus error %s.\n", kind);
 		return action;
 	}
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/dec/prom/Makefile linux-2.4.29-pre3/arch/mips/dec/prom/Makefile
--- linux-2.4.28/arch/mips/dec/prom/Makefile	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/dec/prom/Makefile	2004-12-22 16:06:25.640400008 +0000
@@ -12,7 +12,7 @@ USE_STANDARD_AS_RULE := true
 
 L_TARGET  = rexlib.a
 
-obj-y			+= init.o memory.o cmdline.o identify.o
+obj-y			+= init.o memory.o cmdline.o identify.o console.o
 
 obj-$(CONFIG_MIPS32)	+= locore.o
 obj-$(CONFIG_MIPS64)	+= call_o32.o
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/dec/prom/cmdline.c linux-2.4.29-pre3/arch/mips/dec/prom/cmdline.c
--- linux-2.4.28/arch/mips/dec/prom/cmdline.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/dec/prom/cmdline.c	2004-12-22 16:07:21.316935888 +0000
@@ -2,6 +2,7 @@
  * cmdline.c: read the command line passed to us by the PROM.
  *
  * Copyright (C) 1998 Harald Koerfgen
+ * Copyright (C) 2002, 2004  Maciej W. Rozycki
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -35,6 +36,6 @@ void __init prom_init_cmdline(s32 argc, 
 	}
 
 #ifdef PROM_DEBUG
-	prom_printf("arcs_cmdline: %s\n", &(arcs_cmdline[0]));
+	printk("arcs_cmdline: %s\n", &(arcs_cmdline[0]));
 #endif
 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/dec/prom/console.c linux-2.4.29-pre3/arch/mips/dec/prom/console.c
--- linux-2.4.28/arch/mips/dec/prom/console.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/dec/prom/console.c	2004-12-22 16:06:55.021933336 +0000
@@ -0,0 +1,55 @@
+/*
+ *	arch/mips/dec/prom/console.c
+ *
+ *	DECstation PROM-based early console support.
+ *
+ *	Copyright (C) 2004  Maciej W. Rozycki
+ *
+ *	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/console.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+
+#include <asm/dec/prom.h>
+
+static void __init prom_console_write(struct console *con, const char *s,
+				      unsigned int c)
+{
+	static char sfmt[] __initdata = "%%%us";
+	char fmt[13];
+
+	snprintf(fmt, sizeof(fmt), sfmt, c);
+	prom_printf(fmt, s);
+}
+
+static struct console promcons __initdata = {
+	.name	= "prom",
+	.write	= prom_console_write,
+	.flags	= CON_PRINTBUFFER,
+	.index	= -1,
+};
+
+static int promcons_output __initdata = 0;
+
+void __init register_prom_console(void)
+{
+	if (!promcons_output) {
+		promcons_output = 1;
+		register_console(&promcons);
+	}
+}
+
+void __init unregister_prom_console(void)
+{
+	if (promcons_output) {
+		unregister_console(&promcons);
+		promcons_output = 0;
+	}
+}
+
+void disable_early_printk(void)
+	__attribute__((alias("unregister_prom_console")));
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/dec/prom/identify.c linux-2.4.29-pre3/arch/mips/dec/prom/identify.c
--- linux-2.4.28/arch/mips/dec/prom/identify.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/dec/prom/identify.c	2004-12-22 16:07:40.166070384 +0000
@@ -2,7 +2,7 @@
  * identify.c: machine identification code.
  *
  * Copyright (C) 1998 Harald Koerfgen and Paul M. Antoine
- * Copyright (C) 2002, 2003  Maciej W. Rozycki
+ * Copyright (C) 2002, 2003, 2004  Maciej W. Rozycki
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -100,11 +100,13 @@ void __init prom_identify_arch(u32 magic
 	u32 dec_sysid;
 
 	if (!prom_is_rex(magic)) {
-		dec_sysid = simple_strtoul(prom_getenv("systype"), (char **)0, 0);
+		dec_sysid = simple_strtoul(prom_getenv("systype"),
+					   (char **)0, 0);
 	} else {
 		dec_sysid = rex_getsysid();
 		if (dec_sysid == 0) {
-			prom_printf("Zero sysid returned from PROMs! Assuming PMAX-like machine.\n");
+			printk("Zero sysid returned from PROM! "
+			       "Assuming a PMAX-like machine.\n");
 			dec_sysid = 1;
 		}
 	}
@@ -163,10 +165,8 @@ void __init prom_identify_arch(u32 magic
 	}
 
 	if (mips_machtype == MACH_DSUNKNOWN)
-		prom_printf("This is an %s, id is %x\n",
-			    dec_system_strings[mips_machtype],
-			    dec_systype);
+		printk("This is an %s, id is %x\n",
+		       dec_system_strings[mips_machtype], dec_systype);
 	else
-		prom_printf("This is a %s\n",
-			    dec_system_strings[mips_machtype]);
+		printk("This is a %s\n", dec_system_strings[mips_machtype]);
 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/dec/prom/init.c linux-2.4.29-pre3/arch/mips/dec/prom/init.c
--- linux-2.4.28/arch/mips/dec/prom/init.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/dec/prom/init.c	2004-12-22 16:06:55.507859464 +0000
@@ -2,10 +2,11 @@
  * init.c: PROM library initialisation code.
  *
  * Copyright (C) 1998 Harald Koerfgen
- * Copyright (C) 2002  Maciej W. Rozycki
+ * Copyright (C) 2002, 2004  Maciej W. Rozycki
  */
 #include <linux/config.h>
 #include <linux/init.h>
+#include <linux/string.h>
 #include <linux/types.h>
 
 #include <asm/bootinfo.h>
@@ -34,7 +35,7 @@ int (*__pmax_close)(int);
 
 
 /*
- * Detect which PROM's the DECSTATION has, and set the callback vectors
+ * Detect which PROM the DECSTATION has, and set the callback vectors
  * appropriately.
  */
 void __init which_prom(s32 magic, s32 *prom_vec)
@@ -84,9 +85,15 @@ void __init which_prom(s32 magic, s32 *p
 int __init prom_init(s32 argc, s32 *argv, u32 magic, s32 *prom_vec)
 {
 	extern void dec_machine_halt(void);
+	static char cpu_msg[] __initdata =
+		"Sorry, this kernel is compiled for a wrong CPU type!\n";
+	static char r3k_msg[] __initdata =
+		"Please recompile with \"CONFIG_CPU_R3000 = y\".\n";
+	static char r4k_msg[] __initdata =
+		"Please recompile with \"CONFIG_CPU_R4x00 = y\".\n";
 
 	/*
-	 * Determine which PROM's we have
+	 * Determine which PROM we have
 	 * (and therefore which machine we're on!)
 	 */
 	which_prom(magic, prom_vec);
@@ -94,12 +101,15 @@ int __init prom_init(s32 argc, s32 *argv
 	if (prom_is_rex(magic))
 		rex_clear_cache();
 
+	/* Register the early console.  */
+	register_prom_console();
+
 	/* Were we compiled with the right CPU option? */
 #if defined(CONFIG_CPU_R3000)
 	if ((current_cpu_data.cputype == CPU_R4000SC) ||
 	    (current_cpu_data.cputype == CPU_R4400SC)) {
-		prom_printf("Sorry, this kernel is compiled for the wrong CPU type!\n");
-		prom_printf("Please recompile with \"CONFIG_CPU_R4x00 = y\"\n");
+		printk(cpu_msg);
+		printk(r4k_msg);
 		dec_machine_halt();
 	}
 #endif
@@ -107,8 +117,8 @@ int __init prom_init(s32 argc, s32 *argv
 #if defined(CONFIG_CPU_R4X00)
 	if ((current_cpu_data.cputype == CPU_R3000) ||
 	    (current_cpu_data.cputype == CPU_R3000A)) {
-		prom_printf("Sorry, this kernel is compiled for the wrong CPU type!\n");
-		prom_printf("Please recompile with \"CONFIG_CPU_R3000 = y\"\n");
+		printk(cpu_msg);
+		printk(r3k_msg);
 		dec_machine_halt();
 	}
 #endif
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/dec/setup.c linux-2.4.29-pre3/arch/mips/dec/setup.c
--- linux-2.4.28/arch/mips/dec/setup.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/dec/setup.c	2004-12-22 16:06:26.014343160 +0000
@@ -137,9 +137,9 @@ extern void dec_timer_setup(struct irqac
 void __init decstation_setup(void)
 {
 #ifdef CONFIG_BLK_DEV_INITRD
-       ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
-       initrd_start = (unsigned long)&__rd_start;
-       initrd_end = (unsigned long)&__rd_end;
+	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+	initrd_start = (unsigned long)&__rd_start;
+	initrd_end = (unsigned long)&__rd_end;
 #endif
 	board_be_init = dec_be_init;
 	board_time_init = dec_time_init;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig linux-2.4.29-pre3/arch/mips/defconfig
--- linux-2.4.28/arch/mips/defconfig	2004-12-22 16:17:15.648583744 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig	2004-12-22 16:05:48.993971112 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_KMOD=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -81,7 +85,6 @@ CONFIG_BOOT_ELF32=y
 CONFIG_SWAP_IO_SPACE_L=y
 CONFIG_IRQ_CPU=y
 CONFIG_L1_CACHE_SHIFT=5
-CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_PC_KEYB=y
 # CONFIG_MIPS_AU1000 is not set
@@ -120,11 +123,12 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_BINFMT_IRIX=y
 CONFIG_ARC_CONSOLE=y
 CONFIG_NET=y
-# CONFIG_EISA is not set
 # CONFIG_PCI is not set
+# CONFIG_EISA is not set
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
 # CONFIG_MCA is not set
@@ -145,6 +149,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -174,6 +179,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -220,7 +226,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -313,6 +318,17 @@ CONFIG_SGIWD93_SCSI=y
 # CONFIG_SCSI_AM53C974 is not set
 # CONFIG_SCSI_MEGARAID is not set
 # CONFIG_SCSI_MEGARAID2 is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_SATA_SVW is not set
+# CONFIG_SCSI_ATA_PIIX is not set
+# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SCSI_SATA_PROMISE is not set
+# CONFIG_SCSI_SATA_SX4 is not set
+# CONFIG_SCSI_SATA_SIL is not set
+# CONFIG_SCSI_SATA_SIS is not set
+# CONFIG_SCSI_SATA_ULI is not set
+# CONFIG_SCSI_SATA_VIA is not set
+# CONFIG_SCSI_SATA_VITESSE is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_DTC3280 is not set
@@ -449,6 +465,7 @@ CONFIG_VT_CONSOLE=y
 # CONFIG_SERIAL is not set
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -511,13 +528,11 @@ CONFIG_WATCHDOG=y
 # CONFIG_WDTPCI is not set
 # CONFIG_MACHZ_WDT is not set
 # CONFIG_INDYDOG is not set
-# CONFIG_AMD7XX_TCO is not set
 # CONFIG_SCx200 is not set
 # CONFIG_SCx200_GPIO is not set
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 CONFIG_DS1286=y
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-atlas linux-2.4.29-pre3/arch/mips/defconfig-atlas
--- linux-2.4.28/arch/mips/defconfig-atlas	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-atlas	2004-12-22 16:06:24.602557784 +0000
@@ -24,10 +24,12 @@ CONFIG_EXPERIMENTAL=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -50,6 +52,8 @@ CONFIG_MIPS_ATLAS=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -76,9 +80,7 @@ CONFIG_L1_CACHE_SHIFT=5
 CONFIG_MIPS_BONITO64=y
 CONFIG_MIPS_GT64120=y
 CONFIG_MIPS_MSC=y
-CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
-CONFIG_PCI=y
 CONFIG_SWAP_IO_SPACE_W=y
 CONFIG_SWAP_IO_SPACE_L=y
 # CONFIG_MIPS_AU1000 is not set
@@ -119,8 +121,12 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BUILD_ELF64 is not set
 # CONFIG_BINFMT_IRIX is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+# CONFIG_PCI_NEW is not set
+# CONFIG_PCI_AUTO is not set
 # CONFIG_PCI_NAMES is not set
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -142,6 +148,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -171,6 +178,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
@@ -218,7 +226,6 @@ CONFIG_IP_PNP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -309,6 +316,17 @@ CONFIG_SD_EXTRA_DEVS=40
 # CONFIG_SCSI_AM53C974 is not set
 # CONFIG_SCSI_MEGARAID is not set
 # CONFIG_SCSI_MEGARAID2 is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_SATA_SVW is not set
+# CONFIG_SCSI_ATA_PIIX is not set
+# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SCSI_SATA_PROMISE is not set
+# CONFIG_SCSI_SATA_SX4 is not set
+# CONFIG_SCSI_SATA_SIL is not set
+# CONFIG_SCSI_SATA_SIS is not set
+# CONFIG_SCSI_SATA_ULI is not set
+# CONFIG_SCSI_SATA_VIA is not set
+# CONFIG_SCSI_SATA_VITESSE is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_CPQFCTS is not set
 # CONFIG_SCSI_DMX3191D is not set
@@ -420,6 +438,7 @@ CONFIG_NET_PCI=y
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
+# CONFIG_FORCEDETH is not set
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
 # CONFIG_8139CP is not set
@@ -509,6 +528,7 @@ CONFIG_SERIAL=y
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -551,7 +571,6 @@ CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-bosporus linux-2.4.29-pre3/arch/mips/defconfig-bosporus
--- linux-2.4.28/arch/mips/defconfig-bosporus	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-bosporus	2004-12-22 16:06:24.605557328 +0000
@@ -26,10 +26,12 @@ CONFIG_MIPS_BOSPORUS=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_MIPS_BOSPORUS=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -75,11 +79,7 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_SOC_AU1X00=y
 CONFIG_SOC_AU1500=y
-CONFIG_NEW_TIME_C=y
 CONFIG_PC_KEYB=y
-CONFIG_PCI=y
-CONFIG_NEW_PCI=y
-CONFIG_PCI_AUTO=y
 CONFIG_NONCOHERENT_IO=y
 # CONFIG_MIPS_AU1000 is not set
 
@@ -119,7 +119,11 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_NEW=y
+CONFIG_PCI_AUTO=y
 CONFIG_PCI_NAMES=y
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -138,6 +142,10 @@ CONFIG_HOTPLUG=y
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HOTPLUG_PCI_COMPAQ is not set
 # CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set
+# CONFIG_HOTPLUG_PCI_PCIE is not set
+# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
@@ -151,6 +159,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 # CONFIG_PM is not set
 
 #
@@ -200,7 +209,8 @@ CONFIG_MTD_BOSPORUS=y
 # CONFIG_MTD_XXS1500 is not set
 # CONFIG_MTD_MTX1 is not set
 # CONFIG_MTD_DB1X00 is not set
-# CONFIG_MTD_HYDIII is not set
+# CONFIG_MTD_PB1550 is not set
+# CONFIG_MTD_HYDROGEN3 is not set
 # CONFIG_MTD_MIRAGE is not set
 # CONFIG_MTD_CSTM_MIPS_IXX is not set
 # CONFIG_MTD_OCELOT is not set
@@ -252,6 +262,7 @@ CONFIG_MTD_BOSPORUS=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
@@ -354,7 +365,6 @@ CONFIG_IP_NF_MANGLE=m
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -447,6 +457,17 @@ CONFIG_SCSI_CONSTANTS=y
 # CONFIG_SCSI_AM53C974 is not set
 # CONFIG_SCSI_MEGARAID is not set
 # CONFIG_SCSI_MEGARAID2 is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_SATA_SVW is not set
+# CONFIG_SCSI_ATA_PIIX is not set
+# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SCSI_SATA_PROMISE is not set
+# CONFIG_SCSI_SATA_SX4 is not set
+# CONFIG_SCSI_SATA_SIL is not set
+# CONFIG_SCSI_SATA_SIS is not set
+# CONFIG_SCSI_SATA_ULI is not set
+# CONFIG_SCSI_SATA_VIA is not set
+# CONFIG_SCSI_SATA_VITESSE is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_CPQFCTS is not set
 # CONFIG_SCSI_DMX3191D is not set
@@ -580,6 +601,11 @@ CONFIG_NET_RADIO=y
 # CONFIG_PLX_HERMES is not set
 # CONFIG_TMD_HERMES is not set
 # CONFIG_PCI_HERMES is not set
+
+#
+# Prism54 PCI/PCMCIA GT/Duette Driver - 802.11(a/b/g)
+#
+# CONFIG_PRISM54 is not set
 CONFIG_NET_WIRELESS=y
 
 #
@@ -656,6 +682,7 @@ CONFIG_AU1X00_SERIAL_CONSOLE=y
 # CONFIG_AU1X00_USB_TTY is not set
 # CONFIG_AU1X00_USB_RAW is not set
 # CONFIG_TXX927_SERIAL is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -720,7 +747,6 @@ CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 CONFIG_RTC=y
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -930,7 +956,6 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
-# CONFIG_USB_AX8817X is not set
 # CONFIG_USB_CDCETHER is not set
 # CONFIG_USB_USBNET is not set
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-capcella linux-2.4.29-pre3/arch/mips/defconfig-capcella
--- linux-2.4.28/arch/mips/defconfig-capcella	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-capcella	2004-12-22 16:05:33.172376360 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_KMOD=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -74,11 +78,7 @@ CONFIG_ZAO_CAPCELLA=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_IRQ_CPU=y
-CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
-CONFIG_PCI=y
-CONFIG_NEW_PCI=y
-CONFIG_PCI_AUTO=y
 CONFIG_DUMMY_KEYB=y
 # CONFIG_SCSI is not set
 # CONFIG_MIPS_AU1000 is not set
@@ -116,7 +116,11 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_NEW=y
+CONFIG_PCI_AUTO=y
 # CONFIG_PCI_NAMES is not set
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -138,6 +142,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -167,6 +172,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -213,7 +219,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -271,10 +276,12 @@ CONFIG_BLK_DEV_IDE=y
 #
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
 # CONFIG_IDEDISK_STROKE is not set
 # CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_DELKIN is not set
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -294,6 +301,7 @@ CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_BLK_DEV_ATARAID is not set
 # CONFIG_BLK_DEV_ATARAID_PDC is not set
 # CONFIG_BLK_DEV_ATARAID_HPT is not set
+# CONFIG_BLK_DEV_ATARAID_MEDLEY is not set
 # CONFIG_BLK_DEV_ATARAID_SII is not set
 
 #
@@ -373,6 +381,7 @@ CONFIG_NET_PCI=y
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
+# CONFIG_FORCEDETH is not set
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
 # CONFIG_8139CP is not set
@@ -463,6 +472,7 @@ CONFIG_SERIAL=y
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 # CONFIG_VR41XX_KIU is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
@@ -521,13 +531,11 @@ CONFIG_WATCHDOG=y
 # CONFIG_WDT is not set
 # CONFIG_WDTPCI is not set
 # CONFIG_MACHZ_WDT is not set
-# CONFIG_AMD7XX_TCO is not set
 # CONFIG_SCx200 is not set
 # CONFIG_SCx200_GPIO is not set
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -616,7 +624,7 @@ CONFIG_NFS_FS=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
 # CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
+CONFIG_NFSD_TCP=y
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-cobalt linux-2.4.29-pre3/arch/mips/defconfig-cobalt
--- linux-2.4.28/arch/mips/defconfig-cobalt	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-cobalt	2004-12-22 16:07:06.847135632 +0000
@@ -24,10 +24,12 @@ CONFIG_EXPERIMENTAL=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -50,6 +52,8 @@ CONFIG_MIPS_COBALT=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -74,8 +78,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_BOOT_ELF32=y
 CONFIG_COBALT_LCD=y
 CONFIG_I8259=y
-CONFIG_PCI=y
-CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
 # CONFIG_MIPS_AU1000 is not set
 
@@ -112,7 +114,11 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+# CONFIG_PCI_NEW is not set
+# CONFIG_PCI_AUTO is not set
 # CONFIG_PCI_NAMES is not set
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -134,6 +140,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -163,6 +170,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -205,7 +213,6 @@ CONFIG_INET=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -263,10 +270,12 @@ CONFIG_BLK_DEV_IDE=y
 #
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
 # CONFIG_IDEDISK_STROKE is not set
 # CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_DELKIN is not set
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -295,6 +304,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_WDC_ALI15X3 is not set
 # CONFIG_BLK_DEV_AMD74XX is not set
 # CONFIG_AMD74XX_OVERRIDE is not set
+# CONFIG_BLK_DEV_ATIIXP is not set
 # CONFIG_BLK_DEV_CMD64X is not set
 # CONFIG_BLK_DEV_TRIFLEX is not set
 # CONFIG_BLK_DEV_CY82C693 is not set
@@ -323,6 +333,7 @@ CONFIG_BLK_DEV_VIA82CXXX=y
 # CONFIG_BLK_DEV_ATARAID is not set
 # CONFIG_BLK_DEV_ATARAID_PDC is not set
 # CONFIG_BLK_DEV_ATARAID_HPT is not set
+# CONFIG_BLK_DEV_ATARAID_MEDLEY is not set
 # CONFIG_BLK_DEV_ATARAID_SII is not set
 
 #
@@ -404,6 +415,7 @@ CONFIG_TULIP=y
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
+# CONFIG_FORCEDETH is not set
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
 # CONFIG_8139CP is not set
@@ -493,6 +505,7 @@ CONFIG_SERIAL=y
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=16
 
@@ -535,7 +548,6 @@ CONFIG_UNIX98_PTY_COUNT=16
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 CONFIG_RTC=y
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-csb250 linux-2.4.29-pre3/arch/mips/defconfig-csb250
--- linux-2.4.28/arch/mips/defconfig-csb250	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-csb250	2004-12-22 16:06:19.740296960 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 CONFIG_COGENT_CSB250=y
@@ -52,6 +54,8 @@ CONFIG_COGENT_CSB250=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -75,10 +79,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_SOC_AU1X00=y
 CONFIG_SOC_AU1500=y
-CONFIG_NEW_TIME_C=y
-CONFIG_PCI=y
-CONFIG_NEW_PCI=y
-CONFIG_PCI_AUTO=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_PC_KEYB=y
 # CONFIG_MIPS_AU1000 is not set
@@ -119,8 +119,12 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BUILD_ELF64 is not set
 # CONFIG_BINFMT_IRIX is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_NEW=y
+CONFIG_PCI_AUTO=y
 # CONFIG_PCI_NAMES is not set
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -137,9 +141,6 @@ CONFIG_PCMCIA=m
 # CONFIG_I82092 is not set
 # CONFIG_I82365 is not set
 CONFIG_PCMCIA_AU1X00=m
-# CONFIG_PCMCIA_PB1X00 is not set
-CONFIG_PCMCIA_DB1X00=y
-# CONFIG_PCMCIA_XXS1500 is not set
 
 #
 # PCI Hotplug Support
@@ -147,6 +148,10 @@ CONFIG_PCMCIA_DB1X00=y
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HOTPLUG_PCI_COMPAQ is not set
 # CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set
+# CONFIG_HOTPLUG_PCI_PCIE is not set
+# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
@@ -160,6 +165,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 # CONFIG_PM is not set
 
 #
@@ -190,6 +196,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -252,7 +259,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -310,10 +316,12 @@ CONFIG_BLK_DEV_IDE=y
 #
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
 # CONFIG_IDEDISK_STROKE is not set
 CONFIG_BLK_DEV_IDECS=m
+# CONFIG_BLK_DEV_DELKIN is not set
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -342,6 +350,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_WDC_ALI15X3 is not set
 # CONFIG_BLK_DEV_AMD74XX is not set
 # CONFIG_AMD74XX_OVERRIDE is not set
+# CONFIG_BLK_DEV_ATIIXP is not set
 # CONFIG_BLK_DEV_CMD64X is not set
 # CONFIG_BLK_DEV_TRIFLEX is not set
 # CONFIG_BLK_DEV_CY82C693 is not set
@@ -370,6 +379,7 @@ CONFIG_IDEDMA_AUTO=y
 # CONFIG_BLK_DEV_ATARAID is not set
 # CONFIG_BLK_DEV_ATARAID_PDC is not set
 # CONFIG_BLK_DEV_ATARAID_HPT is not set
+# CONFIG_BLK_DEV_ATARAID_MEDLEY is not set
 # CONFIG_BLK_DEV_ATARAID_SII is not set
 
 #
@@ -546,6 +556,7 @@ CONFIG_AU1X00_SERIAL_CONSOLE=y
 # CONFIG_AU1X00_USB_TTY is not set
 # CONFIG_AU1X00_USB_RAW is not set
 # CONFIG_TXX927_SERIAL is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -610,7 +621,6 @@ CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -844,7 +854,6 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
-# CONFIG_USB_AX8817X is not set
 # CONFIG_USB_CDCETHER is not set
 # CONFIG_USB_USBNET is not set
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-db1000 linux-2.4.29-pre3/arch/mips/defconfig-db1000
--- linux-2.4.28/arch/mips/defconfig-db1000	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-db1000	2004-12-22 16:07:18.907302208 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 CONFIG_MIPS_DB1000=y
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_MIPS_DB1000=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -75,10 +79,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_SOC_AU1X00=y
 CONFIG_SOC_AU1000=y
-CONFIG_NEW_TIME_C=y
-CONFIG_PCI=y
-CONFIG_NEW_PCI=y
-# CONFIG_PCI_AUTO is not set
 CONFIG_NONCOHERENT_IO=y
 CONFIG_PC_KEYB=y
 CONFIG_SWAP_IO_SPACE=y
@@ -120,7 +120,11 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_NEW=y
+# CONFIG_PCI_AUTO is not set
 CONFIG_PCI_NAMES=y
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -137,9 +141,6 @@ CONFIG_PCMCIA=m
 # CONFIG_I82092 is not set
 # CONFIG_I82365 is not set
 CONFIG_PCMCIA_AU1X00=m
-# CONFIG_PCMCIA_PB1X00 is not set
-CONFIG_PCMCIA_DB1X00=y
-# CONFIG_PCMCIA_XXS1500 is not set
 
 #
 # PCI Hotplug Support
@@ -147,6 +148,10 @@ CONFIG_PCMCIA_DB1X00=y
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HOTPLUG_PCI_COMPAQ is not set
 # CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set
+# CONFIG_HOTPLUG_PCI_PCIE is not set
+# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
@@ -160,6 +165,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 # CONFIG_PM is not set
 
 #
@@ -211,7 +217,8 @@ CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_DB1X00=y
 CONFIG_MTD_DB1X00_BOOT=y
 CONFIG_MTD_DB1X00_USER=y
-# CONFIG_MTD_HYDIII is not set
+# CONFIG_MTD_PB1550 is not set
+# CONFIG_MTD_HYDROGEN3 is not set
 # CONFIG_MTD_MIRAGE is not set
 # CONFIG_MTD_CSTM_MIPS_IXX is not set
 # CONFIG_MTD_OCELOT is not set
@@ -263,6 +270,7 @@ CONFIG_MTD_DB1X00_USER=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -325,7 +333,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -383,10 +390,12 @@ CONFIG_BLK_DEV_IDE=y
 #
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
 # CONFIG_IDEDISK_STROKE is not set
 CONFIG_BLK_DEV_IDECS=m
+# CONFIG_BLK_DEV_DELKIN is not set
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -406,6 +415,7 @@ CONFIG_BLK_DEV_IDECS=m
 # CONFIG_BLK_DEV_ATARAID is not set
 # CONFIG_BLK_DEV_ATARAID_PDC is not set
 # CONFIG_BLK_DEV_ATARAID_HPT is not set
+# CONFIG_BLK_DEV_ATARAID_MEDLEY is not set
 # CONFIG_BLK_DEV_ATARAID_SII is not set
 
 #
@@ -626,6 +636,7 @@ CONFIG_AU1X00_SERIAL_CONSOLE=y
 # CONFIG_AU1X00_USB_TTY is not set
 # CONFIG_AU1X00_USB_RAW is not set
 # CONFIG_TXX927_SERIAL is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -690,7 +701,6 @@ CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -890,6 +900,8 @@ CONFIG_SOUND=y
 # CONFIG_SOUND_RME96XX is not set
 # CONFIG_SOUND_SONICVIBES is not set
 CONFIG_SOUND_AU1X00=y
+# CONFIG_SOUND_AU1550_PSC is not set
+# CONFIG_SOUND_AU1550_I2S is not set
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
 # CONFIG_SOUND_MSNDPIN is not set
@@ -979,7 +991,6 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
-# CONFIG_USB_AX8817X is not set
 # CONFIG_USB_CDCETHER is not set
 # CONFIG_USB_USBNET is not set
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-db1100 linux-2.4.29-pre3/arch/mips/defconfig-db1100
--- linux-2.4.28/arch/mips/defconfig-db1100	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-db1100	2004-12-22 16:05:32.806431992 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 CONFIG_MIPS_DB1100=y
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_MIPS_DB1100=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -75,9 +79,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_SOC_AU1X00=y
 CONFIG_SOC_AU1100=y
-CONFIG_NEW_TIME_C=y
-CONFIG_PCI=y
-CONFIG_NEW_PCI=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_PC_KEYB=y
 CONFIG_SWAP_IO_SPACE=y
@@ -119,7 +120,11 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_NEW=y
+# CONFIG_PCI_AUTO is not set
 # CONFIG_PCI_NAMES is not set
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -136,9 +141,6 @@ CONFIG_PCMCIA=m
 # CONFIG_I82092 is not set
 # CONFIG_I82365 is not set
 CONFIG_PCMCIA_AU1X00=m
-# CONFIG_PCMCIA_PB1X00 is not set
-CONFIG_PCMCIA_DB1X00=y
-# CONFIG_PCMCIA_XXS1500 is not set
 
 #
 # PCI Hotplug Support
@@ -146,6 +148,10 @@ CONFIG_PCMCIA_DB1X00=y
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HOTPLUG_PCI_COMPAQ is not set
 # CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set
+# CONFIG_HOTPLUG_PCI_PCIE is not set
+# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
@@ -159,6 +165,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 # CONFIG_PM is not set
 
 #
@@ -210,7 +217,8 @@ CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_DB1X00=y
 # CONFIG_MTD_DB1X00_BOOT is not set
 CONFIG_MTD_DB1X00_USER=y
-# CONFIG_MTD_HYDIII is not set
+# CONFIG_MTD_PB1550 is not set
+# CONFIG_MTD_HYDROGEN3 is not set
 # CONFIG_MTD_MIRAGE is not set
 # CONFIG_MTD_CSTM_MIPS_IXX is not set
 # CONFIG_MTD_OCELOT is not set
@@ -262,6 +270,7 @@ CONFIG_MTD_DB1X00_USER=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -324,7 +333,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -382,10 +390,12 @@ CONFIG_BLK_DEV_IDE=y
 #
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
 # CONFIG_IDEDISK_STROKE is not set
 CONFIG_BLK_DEV_IDECS=m
+# CONFIG_BLK_DEV_DELKIN is not set
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -405,6 +415,7 @@ CONFIG_BLK_DEV_IDECS=m
 # CONFIG_BLK_DEV_ATARAID is not set
 # CONFIG_BLK_DEV_ATARAID_PDC is not set
 # CONFIG_BLK_DEV_ATARAID_HPT is not set
+# CONFIG_BLK_DEV_ATARAID_MEDLEY is not set
 # CONFIG_BLK_DEV_ATARAID_SII is not set
 
 #
@@ -625,6 +636,7 @@ CONFIG_AU1X00_SERIAL_CONSOLE=y
 # CONFIG_AU1X00_USB_TTY is not set
 # CONFIG_AU1X00_USB_RAW is not set
 # CONFIG_TXX927_SERIAL is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -689,7 +701,6 @@ CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -930,6 +941,8 @@ CONFIG_SOUND=y
 # CONFIG_SOUND_RME96XX is not set
 # CONFIG_SOUND_SONICVIBES is not set
 CONFIG_SOUND_AU1X00=y
+# CONFIG_SOUND_AU1550_PSC is not set
+# CONFIG_SOUND_AU1550_I2S is not set
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
 # CONFIG_SOUND_MSNDPIN is not set
@@ -1019,7 +1032,6 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
-# CONFIG_USB_AX8817X is not set
 # CONFIG_USB_CDCETHER is not set
 # CONFIG_USB_USBNET is not set
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-db1500 linux-2.4.29-pre3/arch/mips/defconfig-db1500
--- linux-2.4.28/arch/mips/defconfig-db1500	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-db1500	2004-12-22 16:07:35.045848776 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 CONFIG_MIPS_DB1500=y
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_MIPS_DB1500=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -75,10 +79,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_SOC_AU1X00=y
 CONFIG_SOC_AU1500=y
-CONFIG_NEW_TIME_C=y
-CONFIG_PCI=y
-CONFIG_NEW_PCI=y
-CONFIG_PCI_AUTO=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_PC_KEYB=y
 # CONFIG_MIPS_AU1000 is not set
@@ -119,7 +119,11 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_NEW=y
+CONFIG_PCI_AUTO=y
 # CONFIG_PCI_NAMES is not set
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -136,9 +140,6 @@ CONFIG_PCMCIA=m
 # CONFIG_I82092 is not set
 # CONFIG_I82365 is not set
 CONFIG_PCMCIA_AU1X00=m
-# CONFIG_PCMCIA_PB1X00 is not set
-CONFIG_PCMCIA_DB1X00=y
-# CONFIG_PCMCIA_XXS1500 is not set
 
 #
 # PCI Hotplug Support
@@ -146,6 +147,10 @@ CONFIG_PCMCIA_DB1X00=y
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HOTPLUG_PCI_COMPAQ is not set
 # CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set
+# CONFIG_HOTPLUG_PCI_PCIE is not set
+# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
@@ -159,6 +164,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 # CONFIG_PM is not set
 
 #
@@ -189,6 +195,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -251,7 +258,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -309,10 +315,12 @@ CONFIG_BLK_DEV_IDE=y
 #
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
 # CONFIG_IDEDISK_STROKE is not set
 CONFIG_BLK_DEV_IDECS=m
+# CONFIG_BLK_DEV_DELKIN is not set
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -341,6 +349,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_WDC_ALI15X3 is not set
 # CONFIG_BLK_DEV_AMD74XX is not set
 # CONFIG_AMD74XX_OVERRIDE is not set
+# CONFIG_BLK_DEV_ATIIXP is not set
 # CONFIG_BLK_DEV_CMD64X is not set
 # CONFIG_BLK_DEV_TRIFLEX is not set
 # CONFIG_BLK_DEV_CY82C693 is not set
@@ -369,6 +378,7 @@ CONFIG_IDEDMA_AUTO=y
 # CONFIG_BLK_DEV_ATARAID is not set
 # CONFIG_BLK_DEV_ATARAID_PDC is not set
 # CONFIG_BLK_DEV_ATARAID_HPT is not set
+# CONFIG_BLK_DEV_ATARAID_MEDLEY is not set
 # CONFIG_BLK_DEV_ATARAID_SII is not set
 
 #
@@ -545,6 +555,7 @@ CONFIG_AU1X00_SERIAL_CONSOLE=y
 # CONFIG_AU1X00_USB_TTY is not set
 # CONFIG_AU1X00_USB_RAW is not set
 # CONFIG_TXX927_SERIAL is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -609,7 +620,6 @@ CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -766,6 +776,8 @@ CONFIG_SOUND=y
 # CONFIG_SOUND_RME96XX is not set
 # CONFIG_SOUND_SONICVIBES is not set
 CONFIG_SOUND_AU1X00=y
+# CONFIG_SOUND_AU1550_PSC is not set
+# CONFIG_SOUND_AU1550_I2S is not set
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
 # CONFIG_SOUND_MSNDPIN is not set
@@ -855,7 +867,6 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
-# CONFIG_USB_AX8817X is not set
 # CONFIG_USB_CDCETHER is not set
 # CONFIG_USB_USBNET is not set
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-db1550 linux-2.4.29-pre3/arch/mips/defconfig-db1550
--- linux-2.4.28/arch/mips/defconfig-db1550	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-db1550	2004-12-22 16:06:14.630073832 +0000
@@ -0,0 +1,1087 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+CONFIG_MIPS_DB1550=y
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_COGENT_CSB250 is not set
+# CONFIG_BAGET_MIPS is not set
+# CONFIG_CASIO_E55 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_IBM_WORKPAD is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TANBAC_TB0226 is not set
+# CONFIG_TANBAC_TB0229 is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_VICTOR_MPC30X is not set
+# CONFIG_ZAO_CAPCELLA is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_SOC_AU1X00=y
+CONFIG_SOC_AU1550=y
+CONFIG_NONCOHERENT_IO=y
+CONFIG_PC_KEYB=y
+# CONFIG_MIPS_AU1000 is not set
+
+#
+# CPU selection
+#
+CONFIG_CPU_MIPS32=y
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_CPU_HAS_PREFETCH=y
+# CONFIG_VTAG_ICACHE is not set
+CONFIG_64BIT_PHYS_ADDR=y
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+# CONFIG_CPU_HAS_LLDSCD is not set
+# CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
+
+#
+# General setup
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
+CONFIG_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_NEW=y
+CONFIG_PCI_AUTO=y
+# CONFIG_PCI_NAMES is not set
+# CONFIG_ISA is not set
+# CONFIG_TC is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+CONFIG_HOTPLUG=y
+
+#
+# PCMCIA/CardBus support
+#
+CONFIG_PCMCIA=m
+# CONFIG_CARDBUS is not set
+# CONFIG_TCIC is not set
+# CONFIG_I82092 is not set
+# CONFIG_I82365 is not set
+CONFIG_PCMCIA_AU1X00=m
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+# CONFIG_HOTPLUG_PCI_COMPAQ is not set
+# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set
+# CONFIG_HOTPLUG_PCI_PCIE is not set
+# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_MIPS32_O32 is not set
+# CONFIG_MIPS32_N32 is not set
+# CONFIG_BINFMT_ELF32 is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PB1000 is not set
+# CONFIG_MTD_PB1500 is not set
+# CONFIG_MTD_PB1100 is not set
+# CONFIG_MTD_BOSPORUS is not set
+# CONFIG_MTD_XXS1500 is not set
+# CONFIG_MTD_MTX1 is not set
+# CONFIG_MTD_DB1X00 is not set
+CONFIG_MTD_PB1550=y
+CONFIG_MTD_PB1550_BOOT=y
+CONFIG_MTD_PB1550_USER=y
+# CONFIG_MTD_HYDROGEN3 is not set
+# CONFIG_MTD_MIRAGE is not set
+# CONFIG_MTD_CSTM_MIPS_IXX is not set
+# CONFIG_MTD_OCELOT is not set
+# CONFIG_MTD_LASAT is not set
+# CONFIG_MTD_PCI is not set
+# CONFIG_MTD_PCMCIA is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# 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 is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_CISS_MONITOR_THREAD is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_FILTER=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+
+#
+#   IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
+
+#
+#   IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+
+#
+#    SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+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_HD is not set
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_IDEDISK_STROKE is not set
+# CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_DELKIN is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_BLK_DEV_GENERIC=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+# CONFIG_IDEDMA_PCI_AUTO is not set
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_PCI_WIP is not set
+# CONFIG_BLK_DEV_ADMA100 is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_WDC_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_AMD74XX_OVERRIDE is not set
+# CONFIG_BLK_DEV_ATIIXP is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_HPT34X_AUTODMA is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_PDC202XX_OLD=y
+CONFIG_PDC202XX_BURST=y
+CONFIG_BLK_DEV_PDC202XX_NEW=y
+# CONFIG_PDC202XX_FORCE is not set
+# CONFIG_BLK_DEV_RZ1000 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SIS5513 is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_DMA_NONPCI is not set
+CONFIG_BLK_DEV_PDC202XX=y
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
+# CONFIG_BLK_DEV_ATARAID_MEDLEY is not set
+# CONFIG_BLK_DEV_ATARAID_SII is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_BOOT is not set
+# CONFIG_FUSION_ISENSE is not set
+# CONFIG_FUSION_CTL is not set
+# CONFIG_FUSION_LAN is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MIPS_AU1X00_ENET=y
+# CONFIG_BCM5222_DUAL_PHY is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# PCMCIA network device support
+#
+# CONFIG_NET_PCMCIA is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_KEYBDEV=y
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_UINPUT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+# 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 is not set
+# CONFIG_SYNCLINKMP is not set
+# CONFIG_N_HDLC is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+# CONFIG_SERIAL_TX3912 is not set
+# CONFIG_SERIAL_TX3912_CONSOLE is not set
+# CONFIG_SERIAL_TXX9 is not set
+# CONFIG_SERIAL_TXX9_CONSOLE is not set
+CONFIG_AU1X00_UART=y
+CONFIG_AU1X00_SERIAL_CONSOLE=y
+# CONFIG_AU1X00_USB_TTY is not set
+# CONFIG_AU1X00_USB_RAW is not set
+# CONFIG_TXX927_SERIAL is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_INPUT_SERIO is not set
+# CONFIG_INPUT_SERPORT is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_IPMI_PANIC_EVENT is not set
+# CONFIG_IPMI_DEVICE_INTERFACE is not set
+# CONFIG_IPMI_KCS is not set
+# CONFIG_IPMI_WATCHDOG is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_SCx200 is not set
+# CONFIG_SCx200_GPIO is not set
+# CONFIG_AMD_PM768 is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+
+#
+# Direct Rendering Manager (XFree86 DRI support)
+#
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_PCMCIA_SERIAL_CS is not set
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_AU1X00_GPIO is not set
+# CONFIG_TS_AU1X00_ADS7846 is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_QFMT_V2 is not set
+CONFIG_AUTOFS_FS=y
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+# CONFIG_UMSDOS_FS is not set
+CONFIG_VFAT_FS=y
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+# CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Console drivers
+#
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_MDA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_CLGEN is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_INTEL is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_E1356 is not set
+# CONFIG_FB_IT8181 is not set
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_FBCON_ADVANCED=y
+# CONFIG_FBCON_MFB is not set
+# CONFIG_FBCON_CFB2 is not set
+# CONFIG_FBCON_CFB4 is not set
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+# CONFIG_FBCON_CFB24 is not set
+# CONFIG_FBCON_CFB32 is not set
+# CONFIG_FBCON_AFB is not set
+# CONFIG_FBCON_ILBM is not set
+# CONFIG_FBCON_IPLAN2P2 is not set
+# CONFIG_FBCON_IPLAN2P4 is not set
+# CONFIG_FBCON_IPLAN2P8 is not set
+# CONFIG_FBCON_MAC is not set
+# CONFIG_FBCON_VGA_PLANES is not set
+# CONFIG_FBCON_VGA is not set
+# CONFIG_FBCON_HGA is not set
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+# CONFIG_FBCON_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+# CONFIG_SOUND_ALI5455 is not set
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_FORTE is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_RME96XX is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_AU1X00 is not set
+CONFIG_SOUND_AU1550_PSC=y
+# CONFIG_SOUND_AU1550_I2S is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_MIDI_VIA82CXXX is not set
+# CONFIG_SOUND_OSS is not set
+# CONFIG_SOUND_TVMIXER is not set
+# CONFIG_SOUND_AD1980 is not set
+# CONFIG_SOUND_WM97XX is not set
+
+#
+# USB support
+#
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_BANDWIDTH is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+CONFIG_USB_OHCI=y
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_MIDI is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDDEV is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_TIGL is not set
+# CONFIG_USB_BRLVGER is not set
+# CONFIG_USB_LCD is not set
+
+#
+# Support for USB gadgets
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_RUNTIME_DEBUG is not set
+# CONFIG_KGDB is not set
+# CONFIG_GDB_CONSOLE is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_MIPS_UNCACHED is not set
+CONFIG_LOG_BUF_SHIFT=0
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC32 is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+# CONFIG_FW_LOADER is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-ddb5476 linux-2.4.29-pre3/arch/mips/defconfig-ddb5476
--- linux-2.4.28/arch/mips/defconfig-ddb5476	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-ddb5476	2004-12-22 16:06:34.125110136 +0000
@@ -24,10 +24,12 @@ CONFIG_EXPERIMENTAL=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -50,6 +52,8 @@ CONFIG_EXPERIMENTAL=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 CONFIG_DDB5476=y
@@ -72,14 +76,10 @@ CONFIG_DDB5476=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_ISA=y
-CONFIG_PCI=y
 CONFIG_PC_KEYB=y
 CONFIG_IRQ_CPU=y
 CONFIG_I8259=y
 CONFIG_HAVE_STD_PC_SERIAL_PORT=y
-CONFIG_NEW_PCI=y
-CONFIG_PCI_AUTO=y
-CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
 # CONFIG_MIPS_AU1000 is not set
 
@@ -116,7 +116,11 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_NEW=y
+CONFIG_PCI_AUTO=y
 # CONFIG_PCI_NAMES is not set
 # CONFIG_TC is not set
 # CONFIG_MCA is not set
@@ -137,6 +141,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -166,6 +171,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -211,7 +217,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -269,10 +274,12 @@ CONFIG_BLK_DEV_IDE=y
 #
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
 # CONFIG_IDEDISK_STROKE is not set
 # CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_DELKIN is not set
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -301,6 +308,7 @@ CONFIG_BLK_DEV_IDEPCI=y
 # CONFIG_WDC_ALI15X3 is not set
 # CONFIG_BLK_DEV_AMD74XX is not set
 # CONFIG_AMD74XX_OVERRIDE is not set
+# CONFIG_BLK_DEV_ATIIXP is not set
 # CONFIG_BLK_DEV_CMD64X is not set
 # CONFIG_BLK_DEV_TRIFLEX is not set
 # CONFIG_BLK_DEV_CY82C693 is not set
@@ -328,6 +336,7 @@ CONFIG_BLK_DEV_IDEPCI=y
 # CONFIG_BLK_DEV_ATARAID is not set
 # CONFIG_BLK_DEV_ATARAID_PDC is not set
 # CONFIG_BLK_DEV_ATARAID_HPT is not set
+# CONFIG_BLK_DEV_ATARAID_MEDLEY is not set
 # CONFIG_BLK_DEV_ATARAID_SII is not set
 
 #
@@ -412,6 +421,7 @@ CONFIG_EEPRO100=y
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 CONFIG_NE2K_PCI=y
+# CONFIG_FORCEDETH is not set
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
 # CONFIG_8139CP is not set
@@ -507,6 +517,7 @@ CONFIG_SERIAL=y
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -553,7 +564,6 @@ CONFIG_PSMOUSE=y
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-ddb5477 linux-2.4.29-pre3/arch/mips/defconfig-ddb5477
--- linux-2.4.28/arch/mips/defconfig-ddb5477	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-ddb5477	2004-12-22 16:06:01.407084032 +0000
@@ -24,10 +24,12 @@ CONFIG_EXPERIMENTAL=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -50,6 +52,8 @@ CONFIG_EXPERIMENTAL=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -72,12 +76,8 @@ CONFIG_DDB5477_BUS_FREQUENCY=0
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-CONFIG_PCI=y
-CONFIG_NEW_TIME_C=y
 CONFIG_IRQ_CPU=y
-CONFIG_NEW_PCI=y
 CONFIG_NONCOHERENT_IO=y
-CONFIG_PCI_AUTO=y
 CONFIG_PC_KEYB=y
 CONFIG_I8259=y
 # CONFIG_MIPS_AU1000 is not set
@@ -115,7 +115,11 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_NEW=y
+CONFIG_PCI_AUTO=y
 # CONFIG_PCI_NAMES is not set
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -137,6 +141,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -166,6 +171,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -211,7 +217,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -339,6 +344,7 @@ CONFIG_TULIP=y
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
+# CONFIG_FORCEDETH is not set
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
 # CONFIG_8139CP is not set
@@ -428,6 +434,7 @@ CONFIG_SERIAL=y
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -470,7 +477,6 @@ CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -559,7 +565,7 @@ CONFIG_NFS_FS=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
 # CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
+CONFIG_NFSD_TCP=y
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-decstation linux-2.4.29-pre3/arch/mips/defconfig-decstation
--- linux-2.4.28/arch/mips/defconfig-decstation	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-decstation	2004-12-22 16:07:55.594724872 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_DECSTATION=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -73,10 +77,10 @@ CONFIG_DECSTATION=y
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_EARLY_PRINTK=y
 CONFIG_BOOT_ELF32=y
 CONFIG_IRQ_CPU=y
 CONFIG_L1_CACHE_SHIFT=4
-CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
 # CONFIG_MIPS_AU1000 is not set
 
@@ -111,6 +115,7 @@ CONFIG_CPU_HAS_WB=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
 # CONFIG_PCI is not set
 # CONFIG_ISA is not set
@@ -133,6 +138,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -162,6 +168,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -207,7 +214,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -299,6 +305,17 @@ CONFIG_SCSI_DECNCR=y
 # CONFIG_SCSI_AM53C974 is not set
 # CONFIG_SCSI_MEGARAID is not set
 # CONFIG_SCSI_MEGARAID2 is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_SATA_SVW is not set
+# CONFIG_SCSI_ATA_PIIX is not set
+# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SCSI_SATA_PROMISE is not set
+# CONFIG_SCSI_SATA_SX4 is not set
+# CONFIG_SCSI_SATA_SIL is not set
+# CONFIG_SCSI_SATA_SIS is not set
+# CONFIG_SCSI_SATA_ULI is not set
+# CONFIG_SCSI_SATA_VIA is not set
+# CONFIG_SCSI_SATA_VITESSE is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_DTC3280 is not set
@@ -460,6 +477,7 @@ CONFIG_SERIAL_DEC=y
 CONFIG_SERIAL_DEC_CONSOLE=y
 CONFIG_DZ=y
 CONFIG_ZS=y
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -502,7 +520,6 @@ CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-e55 linux-2.4.29-pre3/arch/mips/defconfig-e55
--- linux-2.4.28/arch/mips/defconfig-e55	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-e55	2004-12-22 16:05:54.411147576 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_CASIO_E55=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -74,7 +78,6 @@ CONFIG_CASIO_E55=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_IRQ_CPU=y
-CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_ISA=y
 CONFIG_DUMMY_KEYB=y
@@ -114,6 +117,7 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
 # CONFIG_PCI is not set
 # CONFIG_TC is not set
@@ -135,6 +139,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -164,6 +169,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -207,7 +213,6 @@ CONFIG_IP_MULTICAST=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -265,10 +270,12 @@ CONFIG_BLK_DEV_IDE=y
 #
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
 # CONFIG_IDEDISK_STROKE is not set
 # CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_DELKIN is not set
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -287,6 +294,7 @@ CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_BLK_DEV_ATARAID is not set
 # CONFIG_BLK_DEV_ATARAID_PDC is not set
 # CONFIG_BLK_DEV_ATARAID_HPT is not set
+# CONFIG_BLK_DEV_ATARAID_MEDLEY is not set
 # CONFIG_BLK_DEV_ATARAID_SII is not set
 
 #
@@ -418,6 +426,7 @@ CONFIG_SERIAL_MANY_PORTS=y
 # CONFIG_SERIAL_MULTIPORT is not set
 # CONFIG_HUB6 is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 # CONFIG_VR41XX_KIU is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
@@ -476,13 +485,11 @@ CONFIG_WATCHDOG=y
 # CONFIG_WDT is not set
 # CONFIG_WDTPCI is not set
 # CONFIG_MACHZ_WDT is not set
-# CONFIG_AMD7XX_TCO is not set
 # CONFIG_SCx200 is not set
 # CONFIG_SCx200_GPIO is not set
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -571,7 +578,7 @@ CONFIG_NFS_FS=y
 # CONFIG_ROOT_NFS is not set
 CONFIG_NFSD=y
 # CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
+CONFIG_NFSD_TCP=y
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-eagle linux-2.4.29-pre3/arch/mips/defconfig-eagle
--- linux-2.4.28/arch/mips/defconfig-eagle	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-eagle	2004-12-22 16:06:26.595254848 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_KMOD=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -75,11 +79,7 @@ CONFIG_VRC4173=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_IRQ_CPU=y
-CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
-CONFIG_PCI=y
-CONFIG_NEW_PCI=y
-CONFIG_PCI_AUTO=y
 CONFIG_DUMMY_KEYB=y
 # CONFIG_SCSI is not set
 # CONFIG_MIPS_AU1000 is not set
@@ -117,7 +117,11 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_NEW=y
+CONFIG_PCI_AUTO=y
 # CONFIG_PCI_NAMES is not set
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -141,6 +145,10 @@ CONFIG_PCMCIA_VRC4173=y
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HOTPLUG_PCI_COMPAQ is not set
 # CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set
+# CONFIG_HOTPLUG_PCI_PCIE is not set
+# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
@@ -154,6 +162,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -209,7 +218,8 @@ CONFIG_MTD_PHYSMAP_BUSWIDTH=4
 # CONFIG_MTD_XXS1500 is not set
 # CONFIG_MTD_MTX1 is not set
 # CONFIG_MTD_DB1X00 is not set
-# CONFIG_MTD_HYDIII is not set
+# CONFIG_MTD_PB1550 is not set
+# CONFIG_MTD_HYDROGEN3 is not set
 # CONFIG_MTD_MIRAGE is not set
 # CONFIG_MTD_CSTM_MIPS_IXX is not set
 # CONFIG_MTD_OCELOT is not set
@@ -261,6 +271,7 @@ CONFIG_MTD_PHYSMAP_BUSWIDTH=4
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -307,7 +318,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -365,10 +375,12 @@ CONFIG_BLK_DEV_IDE=y
 #
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 CONFIG_IDEDISK_MULTI_MODE=y
 # CONFIG_IDEDISK_STROKE is not set
 CONFIG_BLK_DEV_IDECS=y
+# CONFIG_BLK_DEV_DELKIN is not set
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -388,6 +400,7 @@ CONFIG_BLK_DEV_IDECS=y
 # CONFIG_BLK_DEV_ATARAID is not set
 # CONFIG_BLK_DEV_ATARAID_PDC is not set
 # CONFIG_BLK_DEV_ATARAID_HPT is not set
+# CONFIG_BLK_DEV_ATARAID_MEDLEY is not set
 # CONFIG_BLK_DEV_ATARAID_SII is not set
 
 #
@@ -467,6 +480,7 @@ CONFIG_PCNET32=y
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
+# CONFIG_FORCEDETH is not set
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
 # CONFIG_8139CP is not set
@@ -573,6 +587,7 @@ CONFIG_SERIAL=y
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 # CONFIG_VR41XX_KIU is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
@@ -635,13 +650,11 @@ CONFIG_WATCHDOG=y
 # CONFIG_WDT is not set
 # CONFIG_WDTPCI is not set
 # CONFIG_MACHZ_WDT is not set
-# CONFIG_AMD7XX_TCO is not set
 # CONFIG_SCx200 is not set
 # CONFIG_SCx200_GPIO is not set
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -739,7 +752,7 @@ CONFIG_NFS_FS=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
 # CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
+CONFIG_NFSD_TCP=y
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
@@ -882,7 +895,6 @@ CONFIG_USB_PEGASUS=y
 CONFIG_USB_RTL8150=y
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
-# CONFIG_USB_AX8817X is not set
 # CONFIG_USB_CDCETHER is not set
 # CONFIG_USB_USBNET is not set
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-ev64120 linux-2.4.29-pre3/arch/mips/defconfig-ev64120
--- linux-2.4.28/arch/mips/defconfig-ev64120	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-ev64120	2004-12-22 16:05:54.762094224 +0000
@@ -26,10 +26,12 @@ CONFIG_MODULES=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -56,6 +58,8 @@ CONFIG_SYSCLK_100=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -77,10 +81,8 @@ CONFIG_SYSCLK_100=y
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-CONFIG_PCI=y
 CONFIG_MIPS_GT64120=y
 CONFIG_NONCOHERENT_IO=y
-CONFIG_OLD_TIME_C=y
 # CONFIG_MIPS_AU1000 is not set
 
 #
@@ -117,8 +119,12 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BUILD_ELF64 is not set
 # CONFIG_BINFMT_IRIX is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+# CONFIG_PCI_NEW is not set
+# CONFIG_PCI_AUTO is not set
 # CONFIG_PCI_NAMES is not set
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -140,6 +146,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -169,6 +176,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -213,7 +221,6 @@ CONFIG_IP_PNP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -339,6 +346,7 @@ CONFIG_NET_PCI=y
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 CONFIG_NE2K_PCI=y
+# CONFIG_FORCEDETH is not set
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
 # CONFIG_8139CP is not set
@@ -435,6 +443,7 @@ CONFIG_SERIAL=y
 # CONFIG_SERIAL_CONSOLE is not set
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-ev96100 linux-2.4.29-pre3/arch/mips/defconfig-ev96100
--- linux-2.4.28/arch/mips/defconfig-ev96100	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-ev96100	2004-12-22 16:07:21.003983464 +0000
@@ -26,10 +26,12 @@ CONFIG_MODULES=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_MIPS_EV96100=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -73,12 +77,9 @@ CONFIG_MIPS_EV96100=y
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-CONFIG_PCI=y
 CONFIG_MIPS_GT64120=y
 CONFIG_MIPS_GT96100=y
-CONFIG_NEW_PCI=y
 CONFIG_NONCOHERENT_IO=y
-CONFIG_PCI_AUTO=y
 CONFIG_SWAP_IO_SPACE_W=y
 CONFIG_SWAP_IO_SPACE_L=y
 # CONFIG_MIPS_AU1000 is not set
@@ -120,8 +121,12 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BUILD_ELF64 is not set
 # CONFIG_BINFMT_IRIX is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_NEW=y
+CONFIG_PCI_AUTO=y
 CONFIG_PCI_NAMES=y
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -143,6 +148,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -172,6 +178,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -216,7 +223,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -345,6 +351,7 @@ CONFIG_TULIP=y
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
+# CONFIG_FORCEDETH is not set
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
 # CONFIG_8139CP is not set
@@ -434,6 +441,7 @@ CONFIG_SERIAL=y
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-hp-lj linux-2.4.29-pre3/arch/mips/defconfig-hp-lj
--- linux-2.4.28/arch/mips/defconfig-hp-lj	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-hp-lj	2004-12-22 16:06:29.450820736 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_HP_LASERJET=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -74,10 +78,7 @@ CONFIG_HP_LASERJET=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_IRQ_CPU=y
-CONFIG_NEW_TIME_C=y
-CONFIG_NEW_PCI=y
 CONFIG_NONCOHERENT_IO=y
-CONFIG_PCI=y
 # CONFIG_MIPS_AU1000 is not set
 
 #
@@ -114,7 +115,11 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_NEW=y
+# CONFIG_PCI_AUTO is not set
 # CONFIG_PCI_NAMES is not set
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -136,6 +141,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -188,7 +194,8 @@ CONFIG_MTD_PHYSMAP_BUSWIDTH=4
 # CONFIG_MTD_XXS1500 is not set
 # CONFIG_MTD_MTX1 is not set
 # CONFIG_MTD_DB1X00 is not set
-# CONFIG_MTD_HYDIII is not set
+# CONFIG_MTD_PB1550 is not set
+# CONFIG_MTD_HYDROGEN3 is not set
 # CONFIG_MTD_MIRAGE is not set
 # CONFIG_MTD_CSTM_MIPS_IXX is not set
 # CONFIG_MTD_OCELOT is not set
@@ -242,6 +249,7 @@ CONFIG_MTD_NAND_IDS=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -287,7 +295,6 @@ CONFIG_IP_PNP_DHCP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -345,10 +352,12 @@ CONFIG_BLK_DEV_IDE=y
 #
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
 # CONFIG_IDEDISK_STROKE is not set
 # CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_DELKIN is not set
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -377,6 +386,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_WDC_ALI15X3 is not set
 # CONFIG_BLK_DEV_AMD74XX is not set
 # CONFIG_AMD74XX_OVERRIDE is not set
+# CONFIG_BLK_DEV_ATIIXP is not set
 # CONFIG_BLK_DEV_CMD64X is not set
 # CONFIG_BLK_DEV_TRIFLEX is not set
 # CONFIG_BLK_DEV_CY82C693 is not set
@@ -405,6 +415,7 @@ CONFIG_IDEDMA_AUTO=y
 # CONFIG_BLK_DEV_ATARAID is not set
 # CONFIG_BLK_DEV_ATARAID_PDC is not set
 # CONFIG_BLK_DEV_ATARAID_HPT is not set
+# CONFIG_BLK_DEV_ATARAID_MEDLEY is not set
 # CONFIG_BLK_DEV_ATARAID_SII is not set
 
 #
@@ -486,6 +497,7 @@ CONFIG_TULIP=y
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
+# CONFIG_FORCEDETH is not set
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
 # CONFIG_8139CP is not set
@@ -539,6 +551,11 @@ CONFIG_NET_RADIO=y
 # CONFIG_PLX_HERMES is not set
 # CONFIG_TMD_HERMES is not set
 # CONFIG_PCI_HERMES is not set
+
+#
+# Prism54 PCI/PCMCIA GT/Duette Driver - 802.11(a/b/g)
+#
+# CONFIG_PRISM54 is not set
 CONFIG_NET_WIRELESS=y
 
 #
@@ -587,6 +604,7 @@ CONFIG_SERIAL=y
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 # CONFIG_UNIX98_PTYS is not set
 
 #
@@ -628,7 +646,6 @@ CONFIG_SERIAL_CONSOLE=y
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-hydrogen3 linux-2.4.29-pre3/arch/mips/defconfig-hydrogen3
--- linux-2.4.28/arch/mips/defconfig-hydrogen3	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-hydrogen3	2004-12-22 16:06:57.353578872 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 CONFIG_MIPS_HYDROGEN3=y
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_MIPS_HYDROGEN3=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -75,9 +79,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_SOC_AU1X00=y
 CONFIG_SOC_AU1100=y
-CONFIG_NEW_TIME_C=y
-CONFIG_PCI=y
-CONFIG_NEW_PCI=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_PC_KEYB=y
 CONFIG_SWAP_IO_SPACE=y
@@ -119,7 +120,11 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_NEW=y
+# CONFIG_PCI_AUTO is not set
 # CONFIG_PCI_NAMES is not set
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -136,9 +141,6 @@ CONFIG_PCMCIA=m
 # CONFIG_I82092 is not set
 # CONFIG_I82365 is not set
 CONFIG_PCMCIA_AU1X00=m
-# CONFIG_PCMCIA_PB1X00 is not set
-CONFIG_PCMCIA_DB1X00=y
-# CONFIG_PCMCIA_XXS1500 is not set
 
 #
 # PCI Hotplug Support
@@ -146,6 +148,10 @@ CONFIG_PCMCIA_DB1X00=y
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HOTPLUG_PCI_COMPAQ is not set
 # CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set
+# CONFIG_HOTPLUG_PCI_PCIE is not set
+# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
@@ -159,6 +165,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 # CONFIG_PM is not set
 
 #
@@ -208,7 +215,8 @@ CONFIG_MTD_CFI_AMDSTD=y
 # CONFIG_MTD_XXS1500 is not set
 # CONFIG_MTD_MTX1 is not set
 # CONFIG_MTD_DB1X00 is not set
-CONFIG_MTD_HYDIII=y
+# CONFIG_MTD_PB1550 is not set
+CONFIG_MTD_HYDROGEN3=y
 # CONFIG_MTD_MIRAGE is not set
 # CONFIG_MTD_CSTM_MIPS_IXX is not set
 # CONFIG_MTD_OCELOT is not set
@@ -260,6 +268,7 @@ CONFIG_MTD_HYDIII=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -322,7 +331,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -380,10 +388,12 @@ CONFIG_BLK_DEV_IDE=y
 #
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
 # CONFIG_IDEDISK_STROKE is not set
 CONFIG_BLK_DEV_IDECS=m
+# CONFIG_BLK_DEV_DELKIN is not set
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -403,6 +413,7 @@ CONFIG_BLK_DEV_IDECS=m
 # CONFIG_BLK_DEV_ATARAID is not set
 # CONFIG_BLK_DEV_ATARAID_PDC is not set
 # CONFIG_BLK_DEV_ATARAID_HPT is not set
+# CONFIG_BLK_DEV_ATARAID_MEDLEY is not set
 # CONFIG_BLK_DEV_ATARAID_SII is not set
 
 #
@@ -526,51 +537,7 @@ CONFIG_PPPOE=m
 #
 # IrDA (infrared) support
 #
-CONFIG_IRDA=y
-
-#
-# IrDA protocols
-#
-CONFIG_IRLAN=m
-# CONFIG_IRNET is not set
-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 is not set
-# CONFIG_IRPORT_SIR is not set
-
-#
-# Dongle support
-#
-# CONFIG_DONGLE is not set
-
-#
-# FIR device drivers
-#
-# CONFIG_USB_IRDA is not set
-# CONFIG_NSC_FIR is not set
-# CONFIG_WINBOND_FIR is not set
-# CONFIG_TOSHIBA_OLD is not set
-# CONFIG_TOSHIBA_FIR is not set
-CONFIG_AU1000_FIR=m
-# CONFIG_SMC_IRCC_FIR is not set
-# CONFIG_ALI_FIR is not set
-# CONFIG_VLSI_FIR is not set
-# CONFIG_VIA_IRCC_FIR is not set
+# CONFIG_IRDA is not set
 
 #
 # ISDN subsystem
@@ -623,6 +590,7 @@ CONFIG_AU1X00_SERIAL_CONSOLE=y
 # CONFIG_AU1X00_USB_TTY is not set
 # CONFIG_AU1X00_USB_RAW is not set
 # CONFIG_TXX927_SERIAL is not set
+CONFIG_MIPS_HYDROGEN3_BUTTONS=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -687,7 +655,6 @@ CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -928,6 +895,8 @@ CONFIG_SOUND=y
 # CONFIG_SOUND_RME96XX is not set
 # CONFIG_SOUND_SONICVIBES is not set
 CONFIG_SOUND_AU1X00=y
+# CONFIG_SOUND_AU1550_PSC is not set
+# CONFIG_SOUND_AU1550_I2S is not set
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
 # CONFIG_SOUND_MSNDPIN is not set
@@ -1017,7 +986,6 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
-# CONFIG_USB_AX8817X is not set
 # CONFIG_USB_CDCETHER is not set
 # CONFIG_USB_USBNET is not set
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-ip22 linux-2.4.29-pre3/arch/mips/defconfig-ip22
--- linux-2.4.28/arch/mips/defconfig-ip22	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-ip22	2004-12-22 16:07:51.316375280 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_KMOD=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -81,7 +85,6 @@ CONFIG_BOOT_ELF32=y
 CONFIG_SWAP_IO_SPACE_L=y
 CONFIG_IRQ_CPU=y
 CONFIG_L1_CACHE_SHIFT=5
-CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_PC_KEYB=y
 # CONFIG_MIPS_AU1000 is not set
@@ -120,11 +123,12 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_BINFMT_IRIX=y
 CONFIG_ARC_CONSOLE=y
 CONFIG_NET=y
-# CONFIG_EISA is not set
 # CONFIG_PCI is not set
+# CONFIG_EISA is not set
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
 # CONFIG_MCA is not set
@@ -145,6 +149,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -174,6 +179,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -220,7 +226,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -313,6 +318,17 @@ CONFIG_SGIWD93_SCSI=y
 # CONFIG_SCSI_AM53C974 is not set
 # CONFIG_SCSI_MEGARAID is not set
 # CONFIG_SCSI_MEGARAID2 is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_SATA_SVW is not set
+# CONFIG_SCSI_ATA_PIIX is not set
+# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SCSI_SATA_PROMISE is not set
+# CONFIG_SCSI_SATA_SX4 is not set
+# CONFIG_SCSI_SATA_SIL is not set
+# CONFIG_SCSI_SATA_SIS is not set
+# CONFIG_SCSI_SATA_ULI is not set
+# CONFIG_SCSI_SATA_VIA is not set
+# CONFIG_SCSI_SATA_VITESSE is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_DTC3280 is not set
@@ -449,6 +465,7 @@ CONFIG_VT_CONSOLE=y
 # CONFIG_SERIAL is not set
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -511,13 +528,11 @@ CONFIG_WATCHDOG=y
 # CONFIG_WDTPCI is not set
 # CONFIG_MACHZ_WDT is not set
 # CONFIG_INDYDOG is not set
-# CONFIG_AMD7XX_TCO is not set
 # CONFIG_SCx200 is not set
 # CONFIG_SCx200_GPIO is not set
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 CONFIG_DS1286=y
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -607,7 +622,7 @@ CONFIG_NFS_FS=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
 # CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
+CONFIG_NFSD_TCP=y
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-it8172 linux-2.4.29-pre3/arch/mips/defconfig-it8172
--- linux-2.4.28/arch/mips/defconfig-it8172	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-it8172	2004-12-22 16:06:25.155473728 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -53,6 +55,8 @@ CONFIG_MIPS_ITE8172=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -74,14 +78,10 @@ CONFIG_MIPS_ITE8172=y
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-CONFIG_PCI=y
 CONFIG_IT8712=y
 CONFIG_PC_KEYB=y
-CONFIG_NEW_PCI=y
 CONFIG_NONCOHERENT_IO=y
-CONFIG_PCI_AUTO=y
 CONFIG_IT8172_CIR=y
-CONFIG_NEW_TIME_C=y
 # CONFIG_MIPS_AU1000 is not set
 
 #
@@ -117,7 +117,11 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_NEW=y
+CONFIG_PCI_AUTO=y
 CONFIG_PCI_NAMES=y
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -139,6 +143,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -191,7 +196,8 @@ CONFIG_MTD_PHYSMAP_BUSWIDTH=4
 # CONFIG_MTD_XXS1500 is not set
 # CONFIG_MTD_MTX1 is not set
 # CONFIG_MTD_DB1X00 is not set
-# CONFIG_MTD_HYDIII is not set
+# CONFIG_MTD_PB1550 is not set
+# CONFIG_MTD_HYDROGEN3 is not set
 # CONFIG_MTD_MIRAGE is not set
 # CONFIG_MTD_CSTM_MIPS_IXX is not set
 # CONFIG_MTD_OCELOT is not set
@@ -243,6 +249,7 @@ CONFIG_MTD_PHYSMAP_BUSWIDTH=4
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -288,7 +295,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -346,10 +352,12 @@ CONFIG_BLK_DEV_IDE=y
 #
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
 # CONFIG_IDEDISK_STROKE is not set
 # CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_DELKIN is not set
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -378,6 +386,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_WDC_ALI15X3 is not set
 # CONFIG_BLK_DEV_AMD74XX is not set
 # CONFIG_AMD74XX_OVERRIDE is not set
+# CONFIG_BLK_DEV_ATIIXP is not set
 # CONFIG_BLK_DEV_CMD64X is not set
 # CONFIG_BLK_DEV_TRIFLEX is not set
 # CONFIG_BLK_DEV_CY82C693 is not set
@@ -407,6 +416,7 @@ CONFIG_IDEDMA_AUTO=y
 # CONFIG_BLK_DEV_ATARAID is not set
 # CONFIG_BLK_DEV_ATARAID_PDC is not set
 # CONFIG_BLK_DEV_ATARAID_HPT is not set
+# CONFIG_BLK_DEV_ATARAID_MEDLEY is not set
 # CONFIG_BLK_DEV_ATARAID_SII is not set
 
 #
@@ -488,6 +498,7 @@ CONFIG_TULIP=y
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
+# CONFIG_FORCEDETH is not set
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
 # CONFIG_8139CP is not set
@@ -581,6 +592,7 @@ CONFIG_SERIAL_CONSOLE=y
 CONFIG_PC_KEYB=y
 # CONFIG_IT8172_SCR0 is not set
 # CONFIG_IT8172_SCR1 is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -623,7 +635,6 @@ CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-ivr linux-2.4.29-pre3/arch/mips/defconfig-ivr
--- linux-2.4.28/arch/mips/defconfig-ivr	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-ivr	2004-12-22 16:07:10.779537816 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_MIPS_IVR=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -73,13 +77,9 @@ CONFIG_MIPS_IVR=y
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-CONFIG_PCI=y
 CONFIG_PC_KEYB=y
-CONFIG_NEW_PCI=y
 CONFIG_NONCOHERENT_IO=y
-CONFIG_PCI_AUTO=y
 CONFIG_IT8172_CIR=y
-CONFIG_NEW_TIME_C=y
 # CONFIG_MIPS_AU1000 is not set
 
 #
@@ -115,7 +115,11 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_NEW=y
+CONFIG_PCI_AUTO=y
 CONFIG_PCI_NAMES=y
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -137,6 +141,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -166,6 +171,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -211,7 +217,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -269,10 +274,12 @@ CONFIG_BLK_DEV_IDE=y
 #
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
 # CONFIG_IDEDISK_STROKE is not set
 # CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_DELKIN is not set
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -301,6 +308,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_WDC_ALI15X3 is not set
 # CONFIG_BLK_DEV_AMD74XX is not set
 # CONFIG_AMD74XX_OVERRIDE is not set
+# CONFIG_BLK_DEV_ATIIXP is not set
 # CONFIG_BLK_DEV_CMD64X is not set
 # CONFIG_BLK_DEV_TRIFLEX is not set
 # CONFIG_BLK_DEV_CY82C693 is not set
@@ -330,6 +338,7 @@ CONFIG_IDEDMA_AUTO=y
 # CONFIG_BLK_DEV_ATARAID is not set
 # CONFIG_BLK_DEV_ATARAID_PDC is not set
 # CONFIG_BLK_DEV_ATARAID_HPT is not set
+# CONFIG_BLK_DEV_ATARAID_MEDLEY is not set
 # CONFIG_BLK_DEV_ATARAID_SII is not set
 
 #
@@ -411,6 +420,7 @@ CONFIG_TULIP=y
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
+# CONFIG_FORCEDETH is not set
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
 # CONFIG_8139CP is not set
@@ -506,6 +516,7 @@ CONFIG_SERIAL_CONSOLE=y
 CONFIG_QTRONIX_KEYBOARD=y
 CONFIG_IT8172_CIR=y
 # CONFIG_IT8172_SCR0 is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -570,7 +581,6 @@ CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 CONFIG_RTC=y
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -782,7 +792,6 @@ CONFIG_USB_HID=y
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
-# CONFIG_USB_AX8817X is not set
 # CONFIG_USB_CDCETHER is not set
 # CONFIG_USB_USBNET is not set
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-jmr3927 linux-2.4.29-pre3/arch/mips/defconfig-jmr3927
--- linux-2.4.28/arch/mips/defconfig-jmr3927	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-jmr3927	2004-12-22 16:07:06.853134720 +0000
@@ -24,10 +24,12 @@ CONFIG_EXPERIMENTAL=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -50,6 +52,8 @@ CONFIG_EXPERIMENTAL=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -72,10 +76,6 @@ CONFIG_TOSHIBA_JMR3927=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_TOSHIBA_BOARDS=y
-CONFIG_PCI=y
-CONFIG_NEW_PCI=y
-CONFIG_PCI_AUTO=y
-CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_SWAP_IO_SPACE_W=y
 CONFIG_SWAP_IO_SPACE_L=y
@@ -113,8 +113,12 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BUILD_ELF64 is not set
 # CONFIG_BINFMT_IRIX is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_NEW=y
+CONFIG_PCI_AUTO=y
 # CONFIG_PCI_NAMES is not set
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -136,6 +140,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -165,6 +170,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -210,7 +216,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -336,6 +341,7 @@ CONFIG_NET_PCI=y
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
+# CONFIG_FORCEDETH is not set
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
 # CONFIG_8139CP is not set
@@ -448,6 +454,7 @@ CONFIG_SERIAL_NONSTANDARD=y
 # CONFIG_SERIAL_TXX9_CONSOLE is not set
 CONFIG_TXX927_SERIAL=y
 CONFIG_TXX927_SERIAL_CONSOLE=y
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 # CONFIG_UNIX98_PTYS is not set
 
 #
@@ -489,7 +496,6 @@ CONFIG_TXX927_SERIAL_CONSOLE=y
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 CONFIG_DS1742=y
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-lasat linux-2.4.29-pre3/arch/mips/defconfig-lasat
--- linux-2.4.28/arch/mips/defconfig-lasat	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-lasat	2004-12-22 16:07:42.603699808 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -46,6 +48,7 @@ CONFIG_LASAT=y
 CONFIG_PICVUE=y
 CONFIG_PICVUE_PROC=y
 CONFIG_DS1603=y
+CONFIG_MIPS_RTC=y
 CONFIG_LASAT_SYSCTL=y
 # CONFIG_MIPS_ITE8172 is not set
 # CONFIG_MIPS_ATLAS is not set
@@ -56,6 +59,8 @@ CONFIG_LASAT_SYSCTL=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -79,11 +84,9 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BOARD_SCACHE=y
 CONFIG_R5000_CPU_SCACHE=y
-CONFIG_PCI=y
 CONFIG_MIPS_GT64120=y
 CONFIG_MIPS_NILE4=y
 CONFIG_NONCOHERENT_IO=y
-CONFIG_NEW_TIME_C=y
 # CONFIG_MIPS_AU1000 is not set
 
 #
@@ -120,7 +123,11 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+# CONFIG_PCI_NEW is not set
+# CONFIG_PCI_AUTO is not set
 # CONFIG_PCI_NAMES is not set
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -142,6 +149,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -191,7 +199,8 @@ CONFIG_MTD_CFI_AMDSTD=y
 # CONFIG_MTD_XXS1500 is not set
 # CONFIG_MTD_MTX1 is not set
 # CONFIG_MTD_DB1X00 is not set
-# CONFIG_MTD_HYDIII is not set
+# CONFIG_MTD_PB1550 is not set
+# CONFIG_MTD_HYDROGEN3 is not set
 # CONFIG_MTD_MIRAGE is not set
 # CONFIG_MTD_CSTM_MIPS_IXX is not set
 # CONFIG_MTD_OCELOT is not set
@@ -243,6 +252,7 @@ CONFIG_MTD_LASAT=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -284,7 +294,6 @@ CONFIG_INET=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -342,10 +351,12 @@ CONFIG_BLK_DEV_IDE=y
 #
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
 # CONFIG_IDEDISK_STROKE is not set
 # CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_DELKIN is not set
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -374,6 +385,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_WDC_ALI15X3 is not set
 # CONFIG_BLK_DEV_AMD74XX is not set
 # CONFIG_AMD74XX_OVERRIDE is not set
+# CONFIG_BLK_DEV_ATIIXP is not set
 CONFIG_BLK_DEV_CMD64X=y
 # CONFIG_BLK_DEV_TRIFLEX is not set
 # CONFIG_BLK_DEV_CY82C693 is not set
@@ -402,6 +414,7 @@ CONFIG_IDEDMA_AUTO=y
 # CONFIG_BLK_DEV_ATARAID is not set
 # CONFIG_BLK_DEV_ATARAID_PDC is not set
 # CONFIG_BLK_DEV_ATARAID_HPT is not set
+# CONFIG_BLK_DEV_ATARAID_MEDLEY is not set
 # CONFIG_BLK_DEV_ATARAID_SII is not set
 
 #
@@ -481,6 +494,7 @@ CONFIG_PCNET32=y
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
+# CONFIG_FORCEDETH is not set
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
 # CONFIG_8139CP is not set
@@ -570,6 +584,7 @@ CONFIG_SERIAL=y
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -612,7 +627,6 @@ CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-malta linux-2.4.29-pre3/arch/mips/defconfig-malta
--- linux-2.4.28/arch/mips/defconfig-malta	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-malta	2004-12-22 16:06:05.737425720 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_MIPS_MALTA=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -80,12 +84,10 @@ CONFIG_MIPS_BONITO64=y
 CONFIG_MIPS_GT64120=y
 CONFIG_MIPS_MSC=y
 CONFIG_L1_CACHE_SHIFT=5
-CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_SWAP_IO_SPACE_W=y
 CONFIG_SWAP_IO_SPACE_L=y
 CONFIG_PC_KEYB=y
-CONFIG_PCI=y
 # CONFIG_MIPS_AU1000 is not set
 
 #
@@ -124,7 +126,11 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+# CONFIG_PCI_NEW is not set
+# CONFIG_PCI_AUTO is not set
 # CONFIG_PCI_NAMES is not set
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -146,6 +152,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -175,6 +182,7 @@ CONFIG_BLK_DEV_FD=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
@@ -220,7 +228,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -311,6 +318,17 @@ CONFIG_SD_EXTRA_DEVS=40
 # CONFIG_SCSI_AM53C974 is not set
 # CONFIG_SCSI_MEGARAID is not set
 # CONFIG_SCSI_MEGARAID2 is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_SATA_SVW is not set
+# CONFIG_SCSI_ATA_PIIX is not set
+# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SCSI_SATA_PROMISE is not set
+# CONFIG_SCSI_SATA_SX4 is not set
+# CONFIG_SCSI_SATA_SIL is not set
+# CONFIG_SCSI_SATA_SIS is not set
+# CONFIG_SCSI_SATA_ULI is not set
+# CONFIG_SCSI_SATA_VIA is not set
+# CONFIG_SCSI_SATA_VITESSE is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_CPQFCTS is not set
 # CONFIG_SCSI_DMX3191D is not set
@@ -416,6 +434,7 @@ CONFIG_PCNET32=y
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
+# CONFIG_FORCEDETH is not set
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
 # CONFIG_8139CP is not set
@@ -505,6 +524,7 @@ CONFIG_SERIAL=y
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -547,7 +567,6 @@ CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 CONFIG_RTC=y
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -636,7 +655,7 @@ CONFIG_NFS_V3=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
-# CONFIG_NFSD_TCP is not set
+CONFIG_NFSD_TCP=y
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-mirage linux-2.4.29-pre3/arch/mips/defconfig-mirage
--- linux-2.4.28/arch/mips/defconfig-mirage	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-mirage	2004-12-22 16:07:00.601085176 +0000
@@ -26,10 +26,12 @@ CONFIG_MIPS_MIRAGE=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_MIPS_MIRAGE=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -75,11 +79,7 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_SOC_AU1X00=y
 CONFIG_SOC_AU1500=y
-CONFIG_NEW_TIME_C=y
 CONFIG_PC_KEYB=y
-CONFIG_PCI=y
-CONFIG_NEW_PCI=y
-CONFIG_PCI_AUTO=y
 CONFIG_NONCOHERENT_IO=y
 # CONFIG_MIPS_AU1000 is not set
 
@@ -119,7 +119,11 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_NEW=y
+CONFIG_PCI_AUTO=y
 # CONFIG_PCI_NAMES is not set
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -138,6 +142,10 @@ CONFIG_HOTPLUG=y
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HOTPLUG_PCI_COMPAQ is not set
 # CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set
+# CONFIG_HOTPLUG_PCI_PCIE is not set
+# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
@@ -151,12 +159,86 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="root=/dev/mtdblock0 rw ip=off"
 # CONFIG_PM is not set
 
 #
 # Memory Technology Devices (MTD)
 #
-# CONFIG_MTD is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PB1000 is not set
+# CONFIG_MTD_PB1500 is not set
+# CONFIG_MTD_PB1100 is not set
+# CONFIG_MTD_BOSPORUS is not set
+# CONFIG_MTD_XXS1500 is not set
+# CONFIG_MTD_MTX1 is not set
+# CONFIG_MTD_DB1X00 is not set
+# CONFIG_MTD_PB1550 is not set
+# CONFIG_MTD_HYDROGEN3 is not set
+CONFIG_MTD_MIRAGE=y
+# CONFIG_MTD_CSTM_MIPS_IXX is not set
+# CONFIG_MTD_OCELOT is not set
+# CONFIG_MTD_LASAT is not set
+# CONFIG_MTD_PCI is not set
+# CONFIG_MTD_PCMCIA is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
 
 #
 # Parallel port support
@@ -181,6 +263,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -243,7 +326,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -385,7 +467,24 @@ CONFIG_PPPOE=m
 #
 # Wireless LAN (non-hamradio)
 #
-# CONFIG_NET_RADIO is not set
+CONFIG_NET_RADIO=y
+# CONFIG_STRIP is not set
+# CONFIG_WAVELAN is not set
+# CONFIG_ARLAN is not set
+# CONFIG_AIRONET4500 is not set
+# CONFIG_AIRONET4500_NONCS is not set
+# CONFIG_AIRONET4500_PROC is not set
+# CONFIG_AIRO is not set
+# CONFIG_HERMES is not set
+# CONFIG_PLX_HERMES is not set
+# CONFIG_TMD_HERMES is not set
+# CONFIG_PCI_HERMES is not set
+
+#
+# Prism54 PCI/PCMCIA GT/Duette Driver - 802.11(a/b/g)
+#
+# CONFIG_PRISM54 is not set
+CONFIG_NET_WIRELESS=y
 
 #
 # Token Ring devices
@@ -461,19 +560,33 @@ CONFIG_AU1X00_SERIAL_CONSOLE=y
 # CONFIG_AU1X00_USB_TTY is not set
 # CONFIG_AU1X00_USB_RAW is not set
 # CONFIG_TXX927_SERIAL is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
 #
 # I2C support
 #
-# CONFIG_I2C is not set
+CONFIG_I2C=y
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_PHILIPSPAR is not set
+# CONFIG_I2C_ELV is not set
+# CONFIG_I2C_VELLEMAN is not set
+# CONFIG_SCx200_I2C is not set
+# CONFIG_SCx200_ACB is not set
+# CONFIG_I2C_ALGOPCF is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_PROC=y
 
 #
 # Mice
 #
 # CONFIG_BUSMOUSE is not set
-# CONFIG_MOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+# CONFIG_MK712_MOUSE is not set
 
 #
 # Joysticks
@@ -525,7 +638,6 @@ CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 CONFIG_RTC=y
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -570,7 +682,8 @@ CONFIG_AUTOFS_FS=y
 # CONFIG_VFAT_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
-# CONFIG_JFFS2_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
 # CONFIG_CRAMFS is not set
 CONFIG_TMPFS=y
 CONFIG_RAMFS=y
@@ -653,7 +766,50 @@ CONFIG_MSDOS_PARTITION=y
 #
 # Frame-buffer support
 #
-# CONFIG_FB is not set
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_CLGEN is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_INTEL is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_E1356 is not set
+# CONFIG_FB_IT8181 is not set
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_FBCON_ADVANCED=y
+# CONFIG_FBCON_MFB is not set
+# CONFIG_FBCON_CFB2 is not set
+# CONFIG_FBCON_CFB4 is not set
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+# CONFIG_FBCON_CFB24 is not set
+# CONFIG_FBCON_CFB32 is not set
+# CONFIG_FBCON_AFB is not set
+# CONFIG_FBCON_ILBM is not set
+# CONFIG_FBCON_IPLAN2P2 is not set
+# CONFIG_FBCON_IPLAN2P4 is not set
+# CONFIG_FBCON_IPLAN2P8 is not set
+# CONFIG_FBCON_MAC is not set
+# CONFIG_FBCON_VGA_PLANES is not set
+# CONFIG_FBCON_VGA is not set
+# CONFIG_FBCON_HGA is not set
+CONFIG_FBCON_FONTWIDTH8_ONLY=y
+CONFIG_FBCON_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
 
 #
 # Sound
@@ -676,6 +832,8 @@ CONFIG_SOUND=y
 # CONFIG_SOUND_RME96XX is not set
 # CONFIG_SOUND_SONICVIBES is not set
 CONFIG_SOUND_AU1X00=y
+# CONFIG_SOUND_AU1550_PSC is not set
+# CONFIG_SOUND_AU1550_I2S is not set
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
 # CONFIG_SOUND_MSNDPIN is not set
@@ -684,7 +842,7 @@ CONFIG_SOUND_AU1X00=y
 # CONFIG_SOUND_OSS is not set
 # CONFIG_SOUND_TVMIXER is not set
 # CONFIG_SOUND_AD1980 is not set
-# CONFIG_SOUND_WM97XX is not set
+CONFIG_SOUND_WM97XX=y
 
 #
 # USB support
@@ -765,7 +923,6 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
-# CONFIG_USB_AX8817X is not set
 # CONFIG_USB_CDCETHER is not set
 # CONFIG_USB_USBNET is not set
 
@@ -819,6 +976,6 @@ CONFIG_LOG_BUF_SHIFT=0
 # Library routines
 #
 # CONFIG_CRC32 is not set
-CONFIG_ZLIB_INFLATE=m
-CONFIG_ZLIB_DEFLATE=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
 # CONFIG_FW_LOADER is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-mpc30x linux-2.4.29-pre3/arch/mips/defconfig-mpc30x
--- linux-2.4.28/arch/mips/defconfig-mpc30x	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-mpc30x	2004-12-22 16:06:18.890426160 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_KMOD=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -75,12 +79,7 @@ CONFIG_VRC4173=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_IRQ_CPU=y
-CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
-CONFIG_PCI=y
-CONFIG_NEW_PCI=y
-CONFIG_PCI_AUTO=y
-CONFIG_DUMMY_KEYB=y
 # CONFIG_SCSI is not set
 # CONFIG_MIPS_AU1000 is not set
 
@@ -117,7 +116,11 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_NEW=y
+CONFIG_PCI_AUTO=y
 # CONFIG_PCI_NAMES is not set
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -139,6 +142,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -168,6 +172,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -214,7 +219,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -396,6 +400,7 @@ CONFIG_SERIAL=y
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 # CONFIG_VR41XX_KIU is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
@@ -439,7 +444,6 @@ CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -671,7 +675,6 @@ CONFIG_USB_PEGASUS=y
 CONFIG_USB_RTL8150=y
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
-# CONFIG_USB_AX8817X is not set
 # CONFIG_USB_CDCETHER is not set
 # CONFIG_USB_USBNET is not set
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-mtx-1 linux-2.4.29-pre3/arch/mips/defconfig-mtx-1
--- linux-2.4.28/arch/mips/defconfig-mtx-1	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-mtx-1	2004-12-22 16:07:06.009263008 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 CONFIG_MIPS_MTX1=y
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_MIPS_MTX1=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -75,10 +79,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_SOC_AU1X00=y
 CONFIG_SOC_AU1500=y
-CONFIG_NEW_TIME_C=y
-CONFIG_PCI=y
-CONFIG_NEW_PCI=y
-CONFIG_PCI_AUTO=y
 CONFIG_NONCOHERENT_IO=y
 # CONFIG_MIPS_AU1000 is not set
 
@@ -118,7 +118,11 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_NEW=y
+CONFIG_PCI_AUTO=y
 CONFIG_PCI_NAMES=y
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -140,6 +144,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 # CONFIG_PM is not set
 
 #
@@ -189,7 +194,8 @@ CONFIG_MTD_CFI_AMDSTD=y
 # CONFIG_MTD_XXS1500 is not set
 CONFIG_MTD_MTX1=y
 # CONFIG_MTD_DB1X00 is not set
-# CONFIG_MTD_HYDIII is not set
+# CONFIG_MTD_PB1550 is not set
+# CONFIG_MTD_HYDROGEN3 is not set
 # CONFIG_MTD_MIRAGE is not set
 # CONFIG_MTD_CSTM_MIPS_IXX is not set
 # CONFIG_MTD_OCELOT is not set
@@ -241,6 +247,7 @@ CONFIG_MTD_MTX1=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=m
@@ -356,7 +363,6 @@ CONFIG_IP_NF_ARPFILTER=m
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 CONFIG_VLAN_8021Q=m
@@ -389,12 +395,14 @@ CONFIG_NET_SCHED=y
 CONFIG_NET_SCH_CBQ=m
 CONFIG_NET_SCH_HTB=m
 # CONFIG_NET_SCH_CSZ is not set
+# CONFIG_NET_SCH_HFSC is not set
 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_NETEM is not set
 CONFIG_NET_SCH_DSMARK=m
 CONFIG_NET_SCH_INGRESS=m
 CONFIG_NET_QOS=y
@@ -471,6 +479,17 @@ CONFIG_SR_EXTRA_DEVS=2
 # CONFIG_SCSI_AM53C974 is not set
 # CONFIG_SCSI_MEGARAID is not set
 # CONFIG_SCSI_MEGARAID2 is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_SATA_SVW is not set
+# CONFIG_SCSI_ATA_PIIX is not set
+# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SCSI_SATA_PROMISE is not set
+# CONFIG_SCSI_SATA_SX4 is not set
+# CONFIG_SCSI_SATA_SIL is not set
+# CONFIG_SCSI_SATA_SIS is not set
+# CONFIG_SCSI_SATA_ULI is not set
+# CONFIG_SCSI_SATA_VIA is not set
+# CONFIG_SCSI_SATA_VITESSE is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_CPQFCTS is not set
 # CONFIG_SCSI_DMX3191D is not set
@@ -604,6 +623,11 @@ CONFIG_NET_RADIO=y
 # CONFIG_PLX_HERMES is not set
 # CONFIG_TMD_HERMES is not set
 # CONFIG_PCI_HERMES is not set
+
+#
+# Prism54 PCI/PCMCIA GT/Duette Driver - 802.11(a/b/g)
+#
+# CONFIG_PRISM54 is not set
 CONFIG_NET_WIRELESS=y
 
 #
@@ -677,6 +701,7 @@ CONFIG_AU1X00_SERIAL_CONSOLE=y
 # CONFIG_AU1X00_USB_TTY is not set
 # CONFIG_AU1X00_USB_RAW is not set
 # CONFIG_TXX927_SERIAL is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -719,7 +744,6 @@ CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -811,12 +835,13 @@ CONFIG_NFS_V3=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
-# CONFIG_NFSD_TCP is not set
+CONFIG_NFSD_TCP=y
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_SMB_FS=m
 # CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_SMB_UNIX is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_NCPFS_PACKET_SIGNING is not set
 # CONFIG_NCPFS_IOCTL_LOCKING is not set
@@ -934,6 +959,8 @@ CONFIG_SOUND=m
 # CONFIG_SOUND_RME96XX is not set
 # CONFIG_SOUND_SONICVIBES is not set
 # CONFIG_SOUND_AU1X00 is not set
+# CONFIG_SOUND_AU1550_PSC is not set
+# CONFIG_SOUND_AU1550_I2S is not set
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
 # CONFIG_SOUND_MSNDPIN is not set
@@ -1065,7 +1092,6 @@ CONFIG_USB_PEGASUS=m
 CONFIG_USB_RTL8150=m
 CONFIG_USB_KAWETH=m
 CONFIG_USB_CATC=m
-# CONFIG_USB_AX8817X is not set
 CONFIG_USB_CDCETHER=m
 CONFIG_USB_USBNET=m
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-nino linux-2.4.29-pre3/arch/mips/defconfig-nino
--- linux-2.4.28/arch/mips/defconfig-nino	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-nino	2004-12-22 16:07:11.755389464 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_KMOD=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -76,7 +80,6 @@ CONFIG_NINO_8MB=y
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_PC_KEYB=y
 # CONFIG_MIPS_AU1000 is not set
@@ -112,6 +115,7 @@ CONFIG_PAGE_SIZE_4KB=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
 # CONFIG_PCI is not set
 # CONFIG_ISA is not set
@@ -134,6 +138,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -163,6 +168,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
@@ -211,7 +217,6 @@ CONFIG_INET=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -334,6 +339,7 @@ CONFIG_SERIAL_TX3912_CONSOLE=y
 # CONFIG_SERIAL_TXX9 is not set
 # CONFIG_SERIAL_TXX9_CONSOLE is not set
 # CONFIG_TXX927_SERIAL is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 # CONFIG_UNIX98_PTYS is not set
 
 #
@@ -375,7 +381,6 @@ CONFIG_SERIAL_TX3912_CONSOLE=y
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-ocelot linux-2.4.29-pre3/arch/mips/defconfig-ocelot
--- linux-2.4.28/arch/mips/defconfig-ocelot	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-ocelot	2004-12-22 16:06:36.245787744 +0000
@@ -24,10 +24,12 @@ CONFIG_EXPERIMENTAL=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -50,6 +52,8 @@ CONFIG_MOMENCO_OCELOT=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -71,12 +75,10 @@ CONFIG_MOMENCO_OCELOT=y
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-CONFIG_PCI=y
 CONFIG_SYSCLK_100=y
 CONFIG_SWAP_IO_SPACE_W=y
 CONFIG_SWAP_IO_SPACE_L=y
 CONFIG_NONCOHERENT_IO=y
-CONFIG_OLD_TIME_C=y
 # CONFIG_MIPS_AU1000 is not set
 
 #
@@ -116,8 +118,12 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BUILD_ELF64 is not set
 # CONFIG_BINFMT_IRIX is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+# CONFIG_PCI_NEW is not set
+# CONFIG_PCI_AUTO is not set
 CONFIG_PCI_NAMES=y
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -139,6 +145,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -188,7 +195,8 @@ CONFIG_MTD_JEDEC=y
 # CONFIG_MTD_XXS1500 is not set
 # CONFIG_MTD_MTX1 is not set
 # CONFIG_MTD_DB1X00 is not set
-# CONFIG_MTD_HYDIII is not set
+# CONFIG_MTD_PB1550 is not set
+# CONFIG_MTD_HYDROGEN3 is not set
 # CONFIG_MTD_MIRAGE is not set
 # CONFIG_MTD_CSTM_MIPS_IXX is not set
 CONFIG_MTD_OCELOT=y
@@ -245,6 +253,7 @@ CONFIG_MTD_NAND_IDS=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -289,7 +298,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -415,6 +423,7 @@ CONFIG_EEPRO100=y
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
+# CONFIG_FORCEDETH is not set
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
 # CONFIG_8139CP is not set
@@ -504,6 +513,7 @@ CONFIG_SERIAL=y
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -634,7 +644,7 @@ CONFIG_NFS_FS=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
 # CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
+CONFIG_NFSD_TCP=y
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-osprey linux-2.4.29-pre3/arch/mips/defconfig-osprey
--- linux-2.4.28/arch/mips/defconfig-osprey	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-osprey	2004-12-22 16:05:48.705015040 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_KMOD=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -75,7 +79,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_VR4181=y
 CONFIG_IRQ_CPU=y
-CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_DUMMY_KEYB=y
 # CONFIG_SCSI is not set
@@ -114,8 +117,11 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
 # CONFIG_PCI is not set
+# CONFIG_PCI_NEW is not set
+# CONFIG_PCI_AUTO is not set
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
 # CONFIG_MCA is not set
@@ -136,6 +142,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -165,6 +172,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -210,7 +218,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -381,6 +388,7 @@ CONFIG_SERIAL_MANY_PORTS=y
 # CONFIG_SERIAL_MULTIPORT is not set
 # CONFIG_HUB6 is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 # CONFIG_VR41XX_KIU is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
@@ -424,7 +432,6 @@ CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -513,7 +520,7 @@ CONFIG_NFS_FS=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
 # CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
+CONFIG_NFSD_TCP=y
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-pb1000 linux-2.4.29-pre3/arch/mips/defconfig-pb1000
--- linux-2.4.28/arch/mips/defconfig-pb1000	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-pb1000	2004-12-22 16:06:22.670851448 +0000
@@ -26,11 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 CONFIG_MIPS_PB1000=y
-CONFIG_PCI_AUTO=y
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -53,6 +54,8 @@ CONFIG_PCI_AUTO=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -76,9 +79,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_SOC_AU1X00=y
 CONFIG_SOC_AU1000=y
-CONFIG_NEW_TIME_C=y
-CONFIG_PCI=y
-CONFIG_NEW_PCI=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_PC_KEYB=y
 CONFIG_SWAP_IO_SPACE_W=y
@@ -121,7 +121,11 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_NEW=y
+CONFIG_PCI_AUTO=y
 CONFIG_PCI_NAMES=y
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -138,9 +142,6 @@ CONFIG_PCMCIA=m
 # CONFIG_I82092 is not set
 # CONFIG_I82365 is not set
 CONFIG_PCMCIA_AU1X00=m
-CONFIG_PCMCIA_PB1X00=y
-# CONFIG_PCMCIA_DB1X00 is not set
-# CONFIG_PCMCIA_XXS1500 is not set
 
 #
 # PCI Hotplug Support
@@ -148,6 +149,10 @@ CONFIG_PCMCIA_PB1X00=y
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HOTPLUG_PCI_COMPAQ is not set
 # CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set
+# CONFIG_HOTPLUG_PCI_PCIE is not set
+# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
@@ -161,6 +166,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 # CONFIG_PM is not set
 
 #
@@ -210,7 +216,8 @@ CONFIG_MTD_PB1000=y
 # CONFIG_MTD_XXS1500 is not set
 # CONFIG_MTD_MTX1 is not set
 # CONFIG_MTD_DB1X00 is not set
-# CONFIG_MTD_HYDIII is not set
+# CONFIG_MTD_PB1550 is not set
+# CONFIG_MTD_HYDROGEN3 is not set
 # CONFIG_MTD_MIRAGE is not set
 # CONFIG_MTD_CSTM_MIPS_IXX is not set
 # CONFIG_MTD_OCELOT is not set
@@ -262,6 +269,7 @@ CONFIG_MTD_PB1000=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -307,7 +315,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -365,10 +372,12 @@ CONFIG_BLK_DEV_IDE=y
 #
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
 # CONFIG_IDEDISK_STROKE is not set
 CONFIG_BLK_DEV_IDECS=m
+# CONFIG_BLK_DEV_DELKIN is not set
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -388,6 +397,7 @@ CONFIG_BLK_DEV_IDECS=m
 # CONFIG_BLK_DEV_ATARAID is not set
 # CONFIG_BLK_DEV_ATARAID_PDC is not set
 # CONFIG_BLK_DEV_ATARAID_HPT is not set
+# CONFIG_BLK_DEV_ATARAID_MEDLEY is not set
 # CONFIG_BLK_DEV_ATARAID_SII is not set
 
 #
@@ -612,6 +622,7 @@ CONFIG_AU1X00_SERIAL_CONSOLE=y
 # CONFIG_AU1X00_USB_TTY is not set
 # CONFIG_AU1X00_USB_RAW is not set
 # CONFIG_TXX927_SERIAL is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -676,7 +687,6 @@ CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -877,6 +887,8 @@ CONFIG_SOUND=y
 # CONFIG_SOUND_RME96XX is not set
 # CONFIG_SOUND_SONICVIBES is not set
 CONFIG_SOUND_AU1X00=y
+# CONFIG_SOUND_AU1550_PSC is not set
+# CONFIG_SOUND_AU1550_I2S is not set
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
 # CONFIG_SOUND_MSNDPIN is not set
@@ -966,7 +978,6 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
-# CONFIG_USB_AX8817X is not set
 # CONFIG_USB_CDCETHER is not set
 # CONFIG_USB_USBNET is not set
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-pb1100 linux-2.4.29-pre3/arch/mips/defconfig-pb1100
--- linux-2.4.28/arch/mips/defconfig-pb1100	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-pb1100	2004-12-22 16:06:56.717675544 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 CONFIG_MIPS_PB1100=y
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_MIPS_PB1100=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -75,10 +79,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_SOC_AU1X00=y
 CONFIG_SOC_AU1100=y
-CONFIG_NEW_TIME_C=y
-CONFIG_PCI=y
-# CONFIG_PCI_AUTO is not set
-CONFIG_NEW_PCI=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_PC_KEYB=y
 CONFIG_SWAP_IO_SPACE_W=y
@@ -121,7 +121,11 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_NEW=y
+# CONFIG_PCI_AUTO is not set
 CONFIG_PCI_NAMES=y
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -143,6 +147,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 # CONFIG_PM is not set
 
 #
@@ -194,7 +199,8 @@ CONFIG_MTD_PB1100=y
 CONFIG_MTD_PB1500_BOOT=y
 CONFIG_MTD_PB1500_USER=y
 # CONFIG_MTD_DB1X00 is not set
-# CONFIG_MTD_HYDIII is not set
+# CONFIG_MTD_PB1550 is not set
+# CONFIG_MTD_HYDROGEN3 is not set
 # CONFIG_MTD_MIRAGE is not set
 # CONFIG_MTD_CSTM_MIPS_IXX is not set
 # CONFIG_MTD_OCELOT is not set
@@ -246,6 +252,7 @@ CONFIG_MTD_PB1500_USER=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -308,7 +315,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -366,10 +372,12 @@ CONFIG_BLK_DEV_IDE=y
 #
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
 # CONFIG_IDEDISK_STROKE is not set
 # CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_DELKIN is not set
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -389,6 +397,7 @@ CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_BLK_DEV_ATARAID is not set
 # CONFIG_BLK_DEV_ATARAID_PDC is not set
 # CONFIG_BLK_DEV_ATARAID_HPT is not set
+# CONFIG_BLK_DEV_ATARAID_MEDLEY is not set
 # CONFIG_BLK_DEV_ATARAID_SII is not set
 
 #
@@ -604,6 +613,7 @@ CONFIG_AU1X00_SERIAL_CONSOLE=y
 # CONFIG_AU1X00_USB_TTY is not set
 # CONFIG_AU1X00_USB_RAW is not set
 # CONFIG_TXX927_SERIAL is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -668,7 +678,6 @@ CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 CONFIG_RTC=y
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -762,11 +771,12 @@ CONFIG_NFS_FS=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 # CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
+CONFIG_NFSD_TCP=y
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 CONFIG_SMB_FS=m
 # CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_SMB_UNIX is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_NCPFS_PACKET_SIGNING is not set
 # CONFIG_NCPFS_IOCTL_LOCKING is not set
@@ -906,6 +916,8 @@ CONFIG_SOUND=y
 # CONFIG_SOUND_RME96XX is not set
 # CONFIG_SOUND_SONICVIBES is not set
 # CONFIG_SOUND_AU1X00 is not set
+# CONFIG_SOUND_AU1550_PSC is not set
+# CONFIG_SOUND_AU1550_I2S is not set
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
 # CONFIG_SOUND_MSNDPIN is not set
@@ -995,7 +1007,6 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
-# CONFIG_USB_AX8817X is not set
 # CONFIG_USB_CDCETHER is not set
 # CONFIG_USB_USBNET is not set
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-pb1500 linux-2.4.29-pre3/arch/mips/defconfig-pb1500
--- linux-2.4.28/arch/mips/defconfig-pb1500	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-pb1500	2004-12-22 16:06:22.802831384 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 CONFIG_MIPS_PB1500=y
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_MIPS_PB1500=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -75,10 +79,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_SOC_AU1X00=y
 CONFIG_SOC_AU1500=y
-CONFIG_NEW_TIME_C=y
-CONFIG_PCI=y
-CONFIG_NEW_PCI=y
-CONFIG_PCI_AUTO=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_PC_KEYB=y
 # CONFIG_MIPS_AU1000 is not set
@@ -119,7 +119,11 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_NEW=y
+CONFIG_PCI_AUTO=y
 CONFIG_PCI_NAMES=y
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -136,9 +140,6 @@ CONFIG_PCMCIA=m
 # CONFIG_I82092 is not set
 # CONFIG_I82365 is not set
 CONFIG_PCMCIA_AU1X00=m
-CONFIG_PCMCIA_PB1X00=y
-# CONFIG_PCMCIA_DB1X00 is not set
-# CONFIG_PCMCIA_XXS1500 is not set
 
 #
 # PCI Hotplug Support
@@ -146,6 +147,10 @@ CONFIG_PCMCIA_PB1X00=y
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HOTPLUG_PCI_COMPAQ is not set
 # CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set
+# CONFIG_HOTPLUG_PCI_PCIE is not set
+# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
@@ -159,6 +164,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 # CONFIG_PM is not set
 
 #
@@ -210,7 +216,8 @@ CONFIG_MTD_PB1500=y
 CONFIG_MTD_PB1500_BOOT=y
 # CONFIG_MTD_PB1500_USER is not set
 # CONFIG_MTD_DB1X00 is not set
-# CONFIG_MTD_HYDIII is not set
+# CONFIG_MTD_PB1550 is not set
+# CONFIG_MTD_HYDROGEN3 is not set
 # CONFIG_MTD_MIRAGE is not set
 # CONFIG_MTD_CSTM_MIPS_IXX is not set
 # CONFIG_MTD_OCELOT is not set
@@ -262,6 +269,7 @@ CONFIG_MTD_PB1500_BOOT=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -324,7 +332,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -382,10 +389,12 @@ CONFIG_BLK_DEV_IDE=y
 #
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 CONFIG_IDEDISK_MULTI_MODE=y
 # CONFIG_IDEDISK_STROKE is not set
 CONFIG_BLK_DEV_IDECS=m
+# CONFIG_BLK_DEV_DELKIN is not set
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -414,6 +423,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_WDC_ALI15X3 is not set
 # CONFIG_BLK_DEV_AMD74XX is not set
 # CONFIG_AMD74XX_OVERRIDE is not set
+# CONFIG_BLK_DEV_ATIIXP is not set
 # CONFIG_BLK_DEV_CMD64X is not set
 # CONFIG_BLK_DEV_TRIFLEX is not set
 # CONFIG_BLK_DEV_CY82C693 is not set
@@ -442,6 +452,7 @@ CONFIG_IDEDMA_AUTO=y
 # CONFIG_BLK_DEV_ATARAID is not set
 # CONFIG_BLK_DEV_ATARAID_PDC is not set
 # CONFIG_BLK_DEV_ATARAID_HPT is not set
+# CONFIG_BLK_DEV_ATARAID_MEDLEY is not set
 # CONFIG_BLK_DEV_ATARAID_SII is not set
 
 #
@@ -523,6 +534,7 @@ CONFIG_NET_PCI=y
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
+# CONFIG_FORCEDETH is not set
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
 # CONFIG_8139CP is not set
@@ -663,6 +675,7 @@ CONFIG_AU1X00_SERIAL_CONSOLE=y
 # CONFIG_AU1X00_USB_TTY is not set
 # CONFIG_AU1X00_USB_RAW is not set
 # CONFIG_TXX927_SERIAL is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -727,7 +740,6 @@ CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 CONFIG_RTC=y
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -827,11 +839,12 @@ CONFIG_NFS_FS=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 # CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
+CONFIG_NFSD_TCP=y
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 CONFIG_SMB_FS=m
 # CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_SMB_UNIX is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_NCPFS_PACKET_SIGNING is not set
 # CONFIG_NCPFS_IOCTL_LOCKING is not set
@@ -972,6 +985,8 @@ CONFIG_SOUND=y
 # CONFIG_SOUND_RME96XX is not set
 # CONFIG_SOUND_SONICVIBES is not set
 CONFIG_SOUND_AU1X00=y
+# CONFIG_SOUND_AU1550_PSC is not set
+# CONFIG_SOUND_AU1550_I2S is not set
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
 # CONFIG_SOUND_MSNDPIN is not set
@@ -1061,7 +1076,6 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
-# CONFIG_USB_AX8817X is not set
 # CONFIG_USB_CDCETHER is not set
 # CONFIG_USB_USBNET is not set
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-pb1550 linux-2.4.29-pre3/arch/mips/defconfig-pb1550
--- linux-2.4.28/arch/mips/defconfig-pb1550	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-pb1550	2004-12-22 16:07:22.630736160 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+CONFIG_MIPS_PB1550=y
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_KMOD=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -75,10 +79,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_SOC_AU1X00=y
 CONFIG_SOC_AU1550=y
-CONFIG_NEW_TIME_C=y
-CONFIG_PCI=y
-CONFIG_NEW_PCI=y
-CONFIG_PCI_AUTO=y
 # CONFIG_NONCOHERENT_IO is not set
 CONFIG_PC_KEYB=y
 # CONFIG_MIPS_AU1000 is not set
@@ -119,15 +119,38 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_NEW=y
+CONFIG_PCI_AUTO=y
 # CONFIG_PCI_NAMES is not set
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
 # CONFIG_MCA is not set
 # CONFIG_SBUS is not set
-# CONFIG_HOTPLUG is not set
-# CONFIG_PCMCIA is not set
+CONFIG_HOTPLUG=y
+
+#
+# PCMCIA/CardBus support
+#
+CONFIG_PCMCIA=m
+# CONFIG_CARDBUS is not set
+# CONFIG_TCIC is not set
+# CONFIG_I82092 is not set
+# CONFIG_I82365 is not set
+CONFIG_PCMCIA_AU1X00=m
+
+#
+# PCI Hotplug Support
+#
 # CONFIG_HOTPLUG_PCI is not set
+# CONFIG_HOTPLUG_PCI_COMPAQ is not set
+# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set
+# CONFIG_HOTPLUG_PCI_PCIE is not set
+# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
@@ -141,12 +164,89 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 # CONFIG_PM is not set
 
 #
 # Memory Technology Devices (MTD)
 #
-# CONFIG_MTD is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_PB1000 is not set
+# CONFIG_MTD_PB1500 is not set
+# CONFIG_MTD_PB1100 is not set
+# CONFIG_MTD_BOSPORUS is not set
+# CONFIG_MTD_XXS1500 is not set
+# CONFIG_MTD_MTX1 is not set
+# CONFIG_MTD_DB1X00 is not set
+CONFIG_MTD_PB1550=y
+CONFIG_MTD_PB1550_BOOT=y
+CONFIG_MTD_PB1550_USER=y
+# CONFIG_MTD_HYDROGEN3 is not set
+# CONFIG_MTD_MIRAGE is not set
+# CONFIG_MTD_CSTM_MIPS_IXX is not set
+# CONFIG_MTD_OCELOT is not set
+# CONFIG_MTD_LASAT is not set
+# CONFIG_MTD_PCI is not set
+# CONFIG_MTD_PCMCIA is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_IDS=m
 
 #
 # Parallel port support
@@ -171,6 +271,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -233,7 +334,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -291,10 +391,12 @@ CONFIG_BLK_DEV_IDE=y
 #
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
-# CONFIG_BLK_DEV_IDEDISK is not set
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
 # CONFIG_IDEDISK_STROKE is not set
-# CONFIG_BLK_DEV_IDECS is not set
+CONFIG_BLK_DEV_IDECS=m
+# CONFIG_BLK_DEV_DELKIN is not set
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -323,6 +425,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_WDC_ALI15X3 is not set
 # CONFIG_BLK_DEV_AMD74XX is not set
 # CONFIG_AMD74XX_OVERRIDE is not set
+# CONFIG_BLK_DEV_ATIIXP is not set
 # CONFIG_BLK_DEV_CMD64X is not set
 # CONFIG_BLK_DEV_TRIFLEX is not set
 # CONFIG_BLK_DEV_CY82C693 is not set
@@ -353,6 +456,7 @@ CONFIG_BLK_DEV_PDC202XX=y
 # CONFIG_BLK_DEV_ATARAID is not set
 # CONFIG_BLK_DEV_ATARAID_PDC is not set
 # CONFIG_BLK_DEV_ATARAID_HPT is not set
+# CONFIG_BLK_DEV_ATARAID_MEDLEY is not set
 # CONFIG_BLK_DEV_ATARAID_SII is not set
 
 #
@@ -464,58 +568,19 @@ CONFIG_PPPOE=m
 # CONFIG_WAN is not set
 
 #
-# Amateur Radio support
+# PCMCIA network device support
 #
-# CONFIG_HAMRADIO is not set
+# CONFIG_NET_PCMCIA is not set
 
 #
-# IrDA (infrared) support
-#
-CONFIG_IRDA=y
-
-#
-# IrDA protocols
-#
-CONFIG_IRLAN=m
-# CONFIG_IRNET is not set
-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 is not set
-# CONFIG_IRPORT_SIR is not set
-
-#
-# Dongle support
+# Amateur Radio support
 #
-# CONFIG_DONGLE is not set
+# CONFIG_HAMRADIO is not set
 
 #
-# FIR device drivers
+# IrDA (infrared) support
 #
-# CONFIG_USB_IRDA is not set
-# CONFIG_NSC_FIR is not set
-# CONFIG_WINBOND_FIR is not set
-# CONFIG_TOSHIBA_OLD is not set
-# CONFIG_TOSHIBA_FIR is not set
-CONFIG_AU1000_FIR=m
-# CONFIG_SMC_IRCC_FIR is not set
-# CONFIG_ALI_FIR is not set
-# CONFIG_VLSI_FIR is not set
-# CONFIG_VIA_IRCC_FIR is not set
+# CONFIG_IRDA is not set
 
 #
 # ISDN subsystem
@@ -568,6 +633,7 @@ CONFIG_AU1X00_SERIAL_CONSOLE=y
 # CONFIG_AU1X00_USB_TTY is not set
 # CONFIG_AU1X00_USB_RAW is not set
 # CONFIG_TXX927_SERIAL is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -632,7 +698,6 @@ CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -647,6 +712,12 @@ CONFIG_UNIX98_PTY_COUNT=256
 # Direct Rendering Manager (XFree86 DRI support)
 #
 # CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_PCMCIA_SERIAL_CS is not set
+# CONFIG_SYNCLINK_CS is not set
 # CONFIG_AU1X00_GPIO is not set
 # CONFIG_TS_AU1X00_ADS7846 is not set
 
@@ -677,7 +748,8 @@ CONFIG_MSDOS_FS=y
 CONFIG_VFAT_FS=y
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
-# CONFIG_JFFS2_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
 # CONFIG_CRAMFS is not set
 CONFIG_TMPFS=y
 CONFIG_RAMFS=y
@@ -848,12 +920,136 @@ CONFIG_FONT_8x16=y
 #
 # Sound
 #
-# CONFIG_SOUND is not set
+CONFIG_SOUND=y
+# CONFIG_SOUND_ALI5455 is not set
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_FORTE is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_RME96XX is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_AU1X00 is not set
+CONFIG_SOUND_AU1550_PSC=y
+# CONFIG_SOUND_AU1550_I2S is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_MIDI_VIA82CXXX is not set
+# CONFIG_SOUND_OSS is not set
+# CONFIG_SOUND_TVMIXER is not set
+# CONFIG_SOUND_AD1980 is not set
+# CONFIG_SOUND_WM97XX is not set
 
 #
 # USB support
 #
-# CONFIG_USB is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_BANDWIDTH is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+CONFIG_USB_OHCI=y
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_MIDI is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDDEV is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_TIGL is not set
+# CONFIG_USB_BRLVGER is not set
+# CONFIG_USB_LCD is not set
 
 #
 # Support for USB gadgets
@@ -886,5 +1082,6 @@ CONFIG_LOG_BUF_SHIFT=0
 # Library routines
 #
 # CONFIG_CRC32 is not set
-CONFIG_ZLIB_INFLATE=m
-CONFIG_ZLIB_DEFLATE=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+# CONFIG_FW_LOADER is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-rbtx4927 linux-2.4.29-pre3/arch/mips/defconfig-rbtx4927
--- linux-2.4.28/arch/mips/defconfig-rbtx4927	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-rbtx4927	2004-12-22 16:05:33.173376208 +0000
@@ -24,10 +24,12 @@ CONFIG_EXPERIMENTAL=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -50,6 +52,8 @@ CONFIG_EXPERIMENTAL=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -71,10 +75,6 @@ CONFIG_TOSHIBA_RBTX4927=y
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-CONFIG_NEW_TIME_C=y
-CONFIG_PCI=y
-CONFIG_NEW_PCI=y
-CONFIG_PCI_AUTO=y
 CONFIG_SWAP_IO_SPACE_W=y
 CONFIG_SWAP_IO_SPACE_L=y
 CONFIG_ISA=y
@@ -114,7 +114,11 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_NEW=y
+CONFIG_PCI_AUTO=y
 # CONFIG_PCI_NAMES is not set
 # CONFIG_TC is not set
 # CONFIG_MCA is not set
@@ -135,6 +139,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -164,6 +169,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -208,7 +214,6 @@ CONFIG_IP_PNP_DHCP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -346,6 +351,7 @@ CONFIG_NET_PCI=y
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
+# CONFIG_FORCEDETH is not set
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
 # CONFIG_8139CP is not set
@@ -460,6 +466,7 @@ CONFIG_SERIAL_NONSTANDARD=y
 CONFIG_SERIAL_TXX9=y
 CONFIG_SERIAL_TXX9_CONSOLE=y
 # CONFIG_TXX927_SERIAL is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 # CONFIG_UNIX98_PTYS is not set
 
 #
@@ -501,7 +508,6 @@ CONFIG_SERIAL_TXX9_CONSOLE=y
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 CONFIG_DS1742=y
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-rm200 linux-2.4.29-pre3/arch/mips/defconfig-rm200
--- linux-2.4.28/arch/mips/defconfig-rm200	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-rm200	2004-12-22 16:07:39.887112792 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_KMOD=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -79,9 +83,7 @@ CONFIG_ARC_PROMLIB=y
 CONFIG_I8259=y
 CONFIG_ISA=y
 CONFIG_NONCOHERENT_IO=y
-CONFIG_OLD_TIME_C=y
 CONFIG_PC_KEYB=y
-CONFIG_PCI=y
 # CONFIG_MIPS_AU1000 is not set
 
 #
@@ -118,8 +120,12 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 # CONFIG_ARC_CONSOLE is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+# CONFIG_PCI_NEW is not set
+# CONFIG_PCI_AUTO is not set
 CONFIG_EISA=y
 # CONFIG_PCI_NAMES is not set
 # CONFIG_TC is not set
@@ -141,6 +147,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -170,6 +177,7 @@ CONFIG_BLK_DEV_FD=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -212,7 +220,6 @@ CONFIG_INET=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -333,6 +340,7 @@ CONFIG_VT_CONSOLE=y
 # CONFIG_SERIAL is not set
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-sb1250-swarm linux-2.4.29-pre3/arch/mips/defconfig-sb1250-swarm
--- linux-2.4.28/arch/mips/defconfig-sb1250-swarm	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-sb1250-swarm	2004-12-22 16:07:53.434053344 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_KMOD=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -84,7 +88,6 @@ CONFIG_SIBYTE_CFE=y
 # CONFIG_SIBYTE_BW_TRACE is not set
 # CONFIG_SIBYTE_SB1250_PROF is not set
 # CONFIG_SIBYTE_TBPROF is not set
-# CONFIG_PCI is not set
 CONFIG_SIBYTE_GENBUS_IDE=y
 CONFIG_SMP_CAPABLE=y
 # CONFIG_SNI_RM200_PCI is not set
@@ -97,7 +100,6 @@ CONFIG_SMP_CAPABLE=y
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-CONFIG_NEW_TIME_C=y
 CONFIG_DUMMY_KEYB=y
 CONFIG_SWAP_IO_SPACE_W=y
 CONFIG_SWAP_IO_SPACE_L=y
@@ -143,9 +145,12 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BUILD_ELF64 is not set
 # CONFIG_BINFMT_IRIX is not set
 CONFIG_NET=y
 # CONFIG_PCI is not set
+# CONFIG_PCI_NEW is not set
+# CONFIG_PCI_AUTO is not set
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
 # CONFIG_MCA is not set
@@ -166,6 +171,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -195,6 +201,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -237,7 +244,6 @@ CONFIG_INET=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -295,10 +301,12 @@ CONFIG_BLK_DEV_IDE=y
 #
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
 # CONFIG_IDEDISK_STROKE is not set
 # CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_DELKIN is not set
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -318,6 +326,7 @@ CONFIG_BLK_DEV_IDE_SIBYTE=y
 # CONFIG_BLK_DEV_ATARAID is not set
 # CONFIG_BLK_DEV_ATARAID_PDC is not set
 # CONFIG_BLK_DEV_ATARAID_HPT is not set
+# CONFIG_BLK_DEV_ATARAID_MEDLEY is not set
 # CONFIG_BLK_DEV_ATARAID_SII is not set
 
 #
@@ -353,7 +362,6 @@ CONFIG_NETDEVICES=y
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
-CONFIG_NET_SB1250_MAC=y
 # CONFIG_SUNLANCE is not set
 # CONFIG_SUNBMAC is not set
 # CONFIG_SUNQE is not set
@@ -377,6 +385,7 @@ CONFIG_NET_SB1250_MAC=y
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
+CONFIG_NET_SB1250_MAC=y
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_FDDI is not set
@@ -460,6 +469,7 @@ CONFIG_SERIAL_NONSTANDARD=y
 CONFIG_SIBYTE_SB1250_DUART=y
 CONFIG_SIBYTE_SB1250_DUART_CONSOLE=y
 CONFIG_SERIAL_CONSOLE=y
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -502,7 +512,6 @@ CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-sead linux-2.4.29-pre3/arch/mips/defconfig-sead
--- linux-2.4.28/arch/mips/defconfig-sead	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-sead	2004-12-22 16:05:43.152859096 +0000
@@ -24,10 +24,12 @@ CONFIG_EXPERIMENTAL=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -50,6 +52,8 @@ CONFIG_MIPS_SEAD=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -73,9 +77,7 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BOOT_ELF32=y
 CONFIG_L1_CACHE_SHIFT=5
-CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
-# CONFIG_PCI is not set
 # CONFIG_MIPS_AU1000 is not set
 
 #
@@ -114,6 +116,7 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 # CONFIG_NET is not set
 # CONFIG_PCI is not set
 # CONFIG_ISA is not set
@@ -136,6 +139,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -165,6 +169,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
@@ -239,6 +244,7 @@ CONFIG_SERIAL=y
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 # CONFIG_UNIX98_PTYS is not set
 
 #
@@ -280,7 +286,6 @@ CONFIG_SERIAL_CONSOLE=y
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-stretch linux-2.4.29-pre3/arch/mips/defconfig-stretch
--- linux-2.4.28/arch/mips/defconfig-stretch	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-stretch	2004-12-22 16:05:31.044699816 +0000
@@ -0,0 +1,721 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_MIPS=y
+CONFIG_MIPS32=y
+# CONFIG_MIPS64 is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODVERSIONS=y
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_MIPS_BOSPORUS is not set
+# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MIPS_DB1000 is not set
+# CONFIG_MIPS_DB1100 is not set
+# CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
+# CONFIG_MIPS_PB1000 is not set
+# CONFIG_MIPS_PB1100 is not set
+# CONFIG_MIPS_PB1500 is not set
+# CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
+# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_MIPS_MTX1 is not set
+# CONFIG_COGENT_CSB250 is not set
+# CONFIG_BAGET_MIPS is not set
+# CONFIG_CASIO_E55 is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_HP_LASERJET is not set
+# CONFIG_IBM_WORKPAD is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+CONFIG_PMC_STRETCH=y
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_NEC_EAGLE is not set
+# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_NINO is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+# CONFIG_TANBAC_TB0226 is not set
+# CONFIG_TANBAC_TB0229 is not set
+# CONFIG_TOSHIBA_JMR3927 is not set
+# CONFIG_TOSHIBA_RBTX4927 is not set
+# CONFIG_VICTOR_MPC30X is not set
+# CONFIG_ZAO_CAPCELLA is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_SWAP_IO_SPACE_W=y
+CONFIG_SWAP_IO_SPACE_L=y
+CONFIG_PCI=y
+CONFIG_BOOT_ELF32=y
+CONFIG_NONCOHERENT_IO=y
+# CONFIG_MIPS_AU1000 is not set
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+CONFIG_CPU_RM7000=y
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_BOARD_SCACHE=y
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_RM7000_CPU_SCACHE=y
+# CONFIG_64BIT_PHYS_ADDR is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+# CONFIG_CPU_HAS_WB is not set
+CONFIG_CPU_HAS_SYNC=y
+
+#
+# General setup
+#
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BUILD_ELF64 is not set
+# CONFIG_BINFMT_IRIX is not set
+CONFIG_NET=y
+CONFIG_PCI=y
+# CONFIG_PCI_NEW is not set
+CONFIG_PCI_AUTO=y
+# CONFIG_PCI_NAMES is not set
+# CONFIG_ISA is not set
+# CONFIG_TC is not set
+# CONFIG_MCA is not set
+# CONFIG_SBUS is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG_PCI is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_MIPS32_COMPAT is not set
+# CONFIG_MIPS32_O32 is not set
+# CONFIG_MIPS32_N32 is not set
+# CONFIG_BINFMT_ELF32 is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_CISS_MONITOR_THREAD is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_NBD=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=32768
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_STATS is not set
+
+#
+# MIPS initrd options
+#
+CONFIG_EMBEDDED_RAMDISK=y
+CONFIG_EMBEDDED_RAMDISK_IMAGE="ramdisk.gz"
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+
+#
+#    SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_SD_EXTRA_DEVS=40
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_SR_EXTRA_DEVS=2
+CONFIG_CHR_DEV_SG=y
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_DEBUG_QUEUES is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AHA1542 is not set
+# CONFIG_SCSI_AHA1740 is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_AM53C974 is not set
+# CONFIG_SCSI_MEGARAID is not set
+# CONFIG_SCSI_MEGARAID2 is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_SATA_SVW is not set
+# CONFIG_SCSI_ATA_PIIX is not set
+# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SCSI_SATA_PROMISE is not set
+# CONFIG_SCSI_SATA_SX4 is not set
+# CONFIG_SCSI_SATA_SIL is not set
+# CONFIG_SCSI_SATA_SIS is not set
+# CONFIG_SCSI_SATA_ULI is not set
+# CONFIG_SCSI_SATA_VIA is not set
+# CONFIG_SCSI_SATA_VITESSE is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_CPQFCTS is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_DMA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_NCR53C8XX is not set
+# CONFIG_SCSI_SYM53C8XX is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PCI2000 is not set
+# CONFIG_SCSI_PCI2220I is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_BOOT is not set
+# CONFIG_FUSION_ISENSE is not set
+# CONFIG_FUSION_CTL is not set
+# CONFIG_FUSION_LAN is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_UINPUT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+# 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 is not set
+# CONFIG_SYNCLINKMP is not set
+# CONFIG_N_HDLC is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+# CONFIG_SERIAL_TX3912 is not set
+# CONFIG_SERIAL_TX3912_CONSOLE is not set
+# CONFIG_SERIAL_TXX9 is not set
+# CONFIG_SERIAL_TXX9_CONSOLE is not set
+# CONFIG_TXX927_SERIAL is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_IPMI_PANIC_EVENT is not set
+# CONFIG_IPMI_DEVICE_INTERFACE is not set
+# CONFIG_IPMI_KCS is not set
+# CONFIG_IPMI_WATCHDOG is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_SCx200 is not set
+# CONFIG_SCx200_GPIO is not set
+# CONFIG_AMD_PM768 is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+
+#
+# Direct Rendering Manager (XFree86 DRI support)
+#
+# CONFIG_DRM is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_QFMT_V2 is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
+# CONFIG_BFS_FS is not set
+CONFIG_EXT3_FS=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_TRACE is not set
+# CONFIG_XFS_DEBUG is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Support for USB gadgets
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_RUNTIME_DEBUG is not set
+# CONFIG_KGDB is not set
+# CONFIG_GDB_CONSOLE is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_MIPS_UNCACHED=y
+CONFIG_LOG_BUF_SHIFT=0
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC32 is not set
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-tb0226 linux-2.4.29-pre3/arch/mips/defconfig-tb0226
--- linux-2.4.28/arch/mips/defconfig-tb0226	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-tb0226	2004-12-22 16:07:22.444764432 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_KMOD=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -74,11 +78,7 @@ CONFIG_TANBAC_TB0226=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_IRQ_CPU=y
-CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
-CONFIG_PCI=y
-CONFIG_NEW_PCI=y
-CONFIG_PCI_AUTO=y
 CONFIG_DUMMY_KEYB=y
 CONFIG_SERIAL_MANY_PORTS=y
 # CONFIG_MIPS_AU1000 is not set
@@ -116,7 +116,11 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_NEW=y
+CONFIG_PCI_AUTO=y
 # CONFIG_PCI_NAMES is not set
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -138,6 +142,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -167,6 +172,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -213,7 +219,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -306,6 +311,17 @@ CONFIG_SCSI_CONSTANTS=y
 # CONFIG_SCSI_AM53C974 is not set
 # CONFIG_SCSI_MEGARAID is not set
 # CONFIG_SCSI_MEGARAID2 is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_SATA_SVW is not set
+# CONFIG_SCSI_ATA_PIIX is not set
+# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SCSI_SATA_PROMISE is not set
+# CONFIG_SCSI_SATA_SX4 is not set
+# CONFIG_SCSI_SATA_SIL is not set
+# CONFIG_SCSI_SATA_SIS is not set
+# CONFIG_SCSI_SATA_ULI is not set
+# CONFIG_SCSI_SATA_VIA is not set
+# CONFIG_SCSI_SATA_VITESSE is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_CPQFCTS is not set
 # CONFIG_SCSI_DMX3191D is not set
@@ -411,6 +427,7 @@ CONFIG_EEPRO100=y
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
+# CONFIG_FORCEDETH is not set
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
 # CONFIG_8139CP is not set
@@ -501,6 +518,7 @@ CONFIG_SERIAL=y
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 # CONFIG_VR41XX_KIU is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
@@ -559,13 +577,11 @@ CONFIG_WATCHDOG=y
 # CONFIG_WDT is not set
 # CONFIG_WDTPCI is not set
 # CONFIG_MACHZ_WDT is not set
-# CONFIG_AMD7XX_TCO is not set
 # CONFIG_SCx200 is not set
 # CONFIG_SCx200_GPIO is not set
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -654,7 +670,7 @@ CONFIG_NFS_FS=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
 # CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
+CONFIG_NFSD_TCP=y
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
@@ -793,7 +809,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
-# CONFIG_USB_AX8817X is not set
 # CONFIG_USB_CDCETHER is not set
 # CONFIG_USB_USBNET is not set
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-tb0229 linux-2.4.29-pre3/arch/mips/defconfig-tb0229
--- linux-2.4.28/arch/mips/defconfig-tb0229	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-tb0229	2004-12-22 16:07:00.615083048 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_KMOD=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -75,11 +79,7 @@ CONFIG_TANBAC_TB0219=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_IRQ_CPU=y
-CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
-CONFIG_PCI=y
-CONFIG_NEW_PCI=y
-CONFIG_PCI_AUTO=y
 CONFIG_DUMMY_KEYB=y
 CONFIG_SERIAL_MANY_PORTS=y
 # CONFIG_MIPS_AU1000 is not set
@@ -117,7 +117,11 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_NEW=y
+CONFIG_PCI_AUTO=y
 # CONFIG_PCI_NAMES is not set
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -139,6 +143,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -168,6 +173,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
@@ -215,7 +221,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -349,6 +354,7 @@ CONFIG_EEPRO100=y
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
+# CONFIG_FORCEDETH is not set
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
 CONFIG_8139CP=y
@@ -439,6 +445,7 @@ CONFIG_SERIAL=y
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 # CONFIG_VR41XX_KIU is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
@@ -497,13 +504,11 @@ CONFIG_WATCHDOG=y
 # CONFIG_WDT is not set
 # CONFIG_WDTPCI is not set
 # CONFIG_MACHZ_WDT is not set
-# CONFIG_AMD7XX_TCO is not set
 # CONFIG_SCx200 is not set
 # CONFIG_SCx200_GPIO is not set
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -592,7 +597,7 @@ CONFIG_NFS_FS=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
 # CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
+CONFIG_NFSD_TCP=y
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-ti1500 linux-2.4.29-pre3/arch/mips/defconfig-ti1500
--- linux-2.4.28/arch/mips/defconfig-ti1500	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-ti1500	2004-12-22 16:07:35.709747848 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 CONFIG_MIPS_XXS1500=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_MIPS_XXS1500=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -75,10 +79,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_SOC_AU1X00=y
 CONFIG_SOC_AU1500=y
-CONFIG_NEW_TIME_C=y
-CONFIG_PCI=y
-CONFIG_NEW_PCI=y
-CONFIG_PCI_AUTO=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_PC_KEYB=y
 # CONFIG_MIPS_AU1000 is not set
@@ -119,7 +119,11 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_NEW=y
+CONFIG_PCI_AUTO=y
 CONFIG_PCI_NAMES=y
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -136,9 +140,6 @@ CONFIG_PCMCIA=m
 # CONFIG_I82092 is not set
 # CONFIG_I82365 is not set
 CONFIG_PCMCIA_AU1X00=m
-# CONFIG_PCMCIA_PB1X00 is not set
-# CONFIG_PCMCIA_DB1X00 is not set
-CONFIG_PCMCIA_XXS1500=y
 
 #
 # PCI Hotplug Support
@@ -146,6 +147,10 @@ CONFIG_PCMCIA_XXS1500=y
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HOTPLUG_PCI_COMPAQ is not set
 # CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set
+# CONFIG_HOTPLUG_PCI_PCIE is not set
+# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
@@ -159,6 +164,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 # CONFIG_PM is not set
 
 #
@@ -208,7 +214,8 @@ CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_XXS1500=y
 # CONFIG_MTD_MTX1 is not set
 # CONFIG_MTD_DB1X00 is not set
-# CONFIG_MTD_HYDIII is not set
+# CONFIG_MTD_PB1550 is not set
+# CONFIG_MTD_HYDROGEN3 is not set
 # CONFIG_MTD_MIRAGE is not set
 # CONFIG_MTD_CSTM_MIPS_IXX is not set
 # CONFIG_MTD_OCELOT is not set
@@ -260,6 +267,7 @@ CONFIG_MTD_XXS1500=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -322,7 +330,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -380,10 +387,12 @@ CONFIG_BLK_DEV_IDE=y
 #
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 CONFIG_IDEDISK_MULTI_MODE=y
 # CONFIG_IDEDISK_STROKE is not set
 CONFIG_BLK_DEV_IDECS=m
+# CONFIG_BLK_DEV_DELKIN is not set
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -403,6 +412,7 @@ CONFIG_BLK_DEV_IDECS=m
 # CONFIG_BLK_DEV_ATARAID is not set
 # CONFIG_BLK_DEV_ATARAID_PDC is not set
 # CONFIG_BLK_DEV_ATARAID_HPT is not set
+# CONFIG_BLK_DEV_ATARAID_MEDLEY is not set
 # CONFIG_BLK_DEV_ATARAID_SII is not set
 
 #
@@ -590,6 +600,7 @@ CONFIG_AU1X00_SERIAL_CONSOLE=y
 # CONFIG_AU1X00_USB_TTY is not set
 # CONFIG_AU1X00_USB_RAW is not set
 # CONFIG_TXX927_SERIAL is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -659,7 +670,6 @@ CONFIG_I2C_PROC=m
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -756,11 +766,12 @@ CONFIG_NFS_FS=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 # CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
+CONFIG_NFSD_TCP=y
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 CONFIG_SMB_FS=m
 # CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_SMB_UNIX is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_NCPFS_PACKET_SIGNING is not set
 # CONFIG_NCPFS_IOCTL_LOCKING is not set
@@ -899,6 +910,8 @@ CONFIG_SOUND=y
 # CONFIG_SOUND_RME96XX is not set
 # CONFIG_SOUND_SONICVIBES is not set
 CONFIG_SOUND_AU1X00=y
+# CONFIG_SOUND_AU1550_PSC is not set
+# CONFIG_SOUND_AU1550_I2S is not set
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
 # CONFIG_SOUND_MSNDPIN is not set
@@ -988,7 +1001,6 @@ CONFIG_USB_HIDDEV=y
 # CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
-# CONFIG_USB_AX8817X is not set
 # CONFIG_USB_CDCETHER is not set
 # CONFIG_USB_USBNET is not set
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-workpad linux-2.4.29-pre3/arch/mips/defconfig-workpad
--- linux-2.4.28/arch/mips/defconfig-workpad	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-workpad	2004-12-22 16:06:45.452388128 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -53,6 +55,8 @@ CONFIG_IBM_WORKPAD=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -75,7 +79,6 @@ CONFIG_IBM_WORKPAD=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_IRQ_CPU=y
-CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_ISA=y
 # CONFIG_SCSI is not set
@@ -114,6 +117,7 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
 # CONFIG_PCI is not set
 # CONFIG_TC is not set
@@ -135,6 +139,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -164,6 +169,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -207,7 +213,6 @@ CONFIG_IP_MULTICAST=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -265,10 +270,12 @@ CONFIG_BLK_DEV_IDE=y
 #
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
 # CONFIG_IDEDISK_STROKE is not set
 # CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_DELKIN is not set
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -287,6 +294,7 @@ CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_BLK_DEV_ATARAID is not set
 # CONFIG_BLK_DEV_ATARAID_PDC is not set
 # CONFIG_BLK_DEV_ATARAID_HPT is not set
+# CONFIG_BLK_DEV_ATARAID_MEDLEY is not set
 # CONFIG_BLK_DEV_ATARAID_SII is not set
 
 #
@@ -418,6 +426,7 @@ CONFIG_SERIAL_MANY_PORTS=y
 # CONFIG_SERIAL_MULTIPORT is not set
 # CONFIG_HUB6 is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 # CONFIG_VR41XX_KIU is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
@@ -476,13 +485,11 @@ CONFIG_WATCHDOG=y
 # CONFIG_WDT is not set
 # CONFIG_WDTPCI is not set
 # CONFIG_MACHZ_WDT is not set
-# CONFIG_AMD7XX_TCO is not set
 # CONFIG_SCx200 is not set
 # CONFIG_SCx200_GPIO is not set
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -571,7 +578,7 @@ CONFIG_NFS_FS=y
 # CONFIG_ROOT_NFS is not set
 CONFIG_NFSD=y
 # CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
+CONFIG_NFSD_TCP=y
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-xxs1500 linux-2.4.29-pre3/arch/mips/defconfig-xxs1500
--- linux-2.4.28/arch/mips/defconfig-xxs1500	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-xxs1500	2004-12-22 16:05:31.045699664 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 CONFIG_MIPS_XXS1500=y
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_MIPS_XXS1500=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -75,10 +79,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_SOC_AU1X00=y
 CONFIG_SOC_AU1500=y
-CONFIG_NEW_TIME_C=y
-CONFIG_PCI=y
-CONFIG_NEW_PCI=y
-CONFIG_PCI_AUTO=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_PC_KEYB=y
 # CONFIG_MIPS_AU1000 is not set
@@ -119,7 +119,11 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+CONFIG_PCI_NEW=y
+CONFIG_PCI_AUTO=y
 CONFIG_PCI_NAMES=y
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -136,9 +140,6 @@ CONFIG_PCMCIA=m
 # CONFIG_I82092 is not set
 # CONFIG_I82365 is not set
 CONFIG_PCMCIA_AU1X00=m
-# CONFIG_PCMCIA_PB1X00 is not set
-# CONFIG_PCMCIA_DB1X00 is not set
-CONFIG_PCMCIA_XXS1500=y
 
 #
 # PCI Hotplug Support
@@ -146,6 +147,10 @@ CONFIG_PCMCIA_XXS1500=y
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HOTPLUG_PCI_COMPAQ is not set
 # CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+# CONFIG_HOTPLUG_PCI_SHPC is not set
+# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set
+# CONFIG_HOTPLUG_PCI_PCIE is not set
+# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
@@ -159,6 +164,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 # CONFIG_PM is not set
 
 #
@@ -208,7 +214,8 @@ CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_XXS1500=y
 # CONFIG_MTD_MTX1 is not set
 # CONFIG_MTD_DB1X00 is not set
-# CONFIG_MTD_HYDIII is not set
+# CONFIG_MTD_PB1550 is not set
+# CONFIG_MTD_HYDROGEN3 is not set
 # CONFIG_MTD_MIRAGE is not set
 # CONFIG_MTD_CSTM_MIPS_IXX is not set
 # CONFIG_MTD_OCELOT is not set
@@ -260,6 +267,7 @@ CONFIG_MTD_XXS1500=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -322,7 +330,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -380,10 +387,12 @@ CONFIG_BLK_DEV_IDE=y
 #
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 CONFIG_IDEDISK_MULTI_MODE=y
 # CONFIG_IDEDISK_STROKE is not set
 CONFIG_BLK_DEV_IDECS=m
+# CONFIG_BLK_DEV_DELKIN is not set
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -412,6 +421,7 @@ CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_WDC_ALI15X3 is not set
 # CONFIG_BLK_DEV_AMD74XX is not set
 # CONFIG_AMD74XX_OVERRIDE is not set
+# CONFIG_BLK_DEV_ATIIXP is not set
 # CONFIG_BLK_DEV_CMD64X is not set
 # CONFIG_BLK_DEV_TRIFLEX is not set
 # CONFIG_BLK_DEV_CY82C693 is not set
@@ -440,6 +450,7 @@ CONFIG_IDEDMA_AUTO=y
 # CONFIG_BLK_DEV_ATARAID is not set
 # CONFIG_BLK_DEV_ATARAID_PDC is not set
 # CONFIG_BLK_DEV_ATARAID_HPT is not set
+# CONFIG_BLK_DEV_ATARAID_MEDLEY is not set
 # CONFIG_BLK_DEV_ATARAID_SII is not set
 
 #
@@ -521,6 +532,7 @@ CONFIG_NET_PCI=y
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
+# CONFIG_FORCEDETH is not set
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
 # CONFIG_8139CP is not set
@@ -659,6 +671,7 @@ CONFIG_AU1X00_SERIAL_CONSOLE=y
 # CONFIG_AU1X00_USB_TTY is not set
 # CONFIG_AU1X00_USB_RAW is not set
 # CONFIG_TXX927_SERIAL is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -701,7 +714,6 @@ CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 CONFIG_RTC=y
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -798,11 +810,12 @@ CONFIG_NFS_FS=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 # CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
+CONFIG_NFSD_TCP=y
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 CONFIG_SMB_FS=m
 # CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_SMB_UNIX is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_NCPFS_PACKET_SIGNING is not set
 # CONFIG_NCPFS_IOCTL_LOCKING is not set
@@ -901,6 +914,8 @@ CONFIG_SOUND=y
 # CONFIG_SOUND_RME96XX is not set
 # CONFIG_SOUND_SONICVIBES is not set
 CONFIG_SOUND_AU1X00=y
+# CONFIG_SOUND_AU1550_PSC is not set
+# CONFIG_SOUND_AU1550_I2S is not set
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
 # CONFIG_SOUND_MSNDPIN is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/defconfig-yosemite linux-2.4.29-pre3/arch/mips/defconfig-yosemite
--- linux-2.4.28/arch/mips/defconfig-yosemite	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/defconfig-yosemite	2004-12-22 16:07:31.196433976 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_KMOD=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -112,9 +116,12 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BUILD_ELF64 is not set
 # CONFIG_BINFMT_IRIX is not set
 CONFIG_NET=y
 # CONFIG_PCI is not set
+# CONFIG_PCI_NEW is not set
+CONFIG_PCI_AUTO=y
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
 # CONFIG_MCA is not set
@@ -135,6 +142,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_ELF32 is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -164,6 +172,7 @@ CONFIG_BINFMT_ELF=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -209,7 +218,6 @@ CONFIG_IP_PNP_DHCP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -301,6 +309,17 @@ CONFIG_CHR_DEV_SG=y
 # CONFIG_SCSI_AM53C974 is not set
 # CONFIG_SCSI_MEGARAID is not set
 # CONFIG_SCSI_MEGARAID2 is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_SATA_SVW is not set
+# CONFIG_SCSI_ATA_PIIX is not set
+# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SCSI_SATA_PROMISE is not set
+# CONFIG_SCSI_SATA_SX4 is not set
+# CONFIG_SCSI_SATA_SIL is not set
+# CONFIG_SCSI_SATA_SIS is not set
+# CONFIG_SCSI_SATA_ULI is not set
+# CONFIG_SCSI_SATA_VIA is not set
+# CONFIG_SCSI_SATA_VITESSE is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_DTC3280 is not set
@@ -458,6 +477,7 @@ CONFIG_SERIAL_NONSTANDARD=y
 # CONFIG_SERIAL_TXX9 is not set
 # CONFIG_SERIAL_TXX9_CONSOLE is not set
 # CONFIG_TXX927_SERIAL is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/galileo-boards/ev96100/time.c linux-2.4.29-pre3/arch/mips/galileo-boards/ev96100/time.c
--- linux-2.4.28/arch/mips/galileo-boards/ev96100/time.c	2003-08-25 11:44:39.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/galileo-boards/ev96100/time.c	2004-12-22 16:06:36.700718584 +0000
@@ -39,6 +39,7 @@
 #include <linux/spinlock.h>
 #include <linux/timex.h>
 
+#include <asm/compiler.h>
 #include <asm/mipsregs.h>
 #include <asm/ptrace.h>
 
@@ -162,11 +163,10 @@ static unsigned long do_fast_gettimeoffs
 			".set\tmips0\n\t"
 			".set\tat\n\t"
 			".set\treorder"
-			:"=&r" (quotient)
-			:"r" (timerhi),
-			 "m" (timerlo),
-			 "r" (tmp),
-			 "r" (USECS_PER_JIFFY));
+			: "=&r" (quotient)
+			: "r" (timerhi), "m" (timerlo),
+			  "r" (tmp), "r" (USECS_PER_JIFFY)
+			: "hi", "lo", GCC_REG_ACCUM);
 		cached_quotient = quotient;
 	}
 
@@ -178,9 +178,9 @@ static unsigned long do_fast_gettimeoffs
 
 	__asm__("multu\t%1,%2\n\t"
 		"mfhi\t%0"
-		:"=r" (res)
-		:"r" (count),
-		 "r" (quotient));
+		: "=r" (res)
+		: "r" (count), "r" (quotient)
+		: "hi", "lo", GCC_REG_ACCUM);
 
 	/*
  	 * Due to possible jiffies inconsistencies, we need to check
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/jazz/Makefile linux-2.4.29-pre3/arch/mips/jazz/Makefile
--- linux-2.4.28/arch/mips/jazz/Makefile	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/jazz/Makefile	2004-12-22 16:06:34.888994008 +0000
@@ -12,7 +12,7 @@ all: jazz.o
 
 O_TARGET := jazz.o
 
-export-syms	:= jazz-ksyms.o
+export-objs	:= jazz-ksyms.o
 obj-y	 	:= int-handler.o irq.o jazzdma.o jazz-ksyms.o reset.o \
 		   rtc-jazz.o setup.o floppy-jazz.o kbd-jazz.o
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/jazz/jazzdma.c linux-2.4.29-pre3/arch/mips/jazz/jazzdma.c
--- linux-2.4.28/arch/mips/jazz/jazzdma.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/jazz/jazzdma.c	2004-12-22 16:07:42.025787664 +0000
@@ -108,7 +108,7 @@ unsigned long vdma_alloc(unsigned long p
 		return VDMA_ERROR;	/* invalid physical address */
 	}
 
-	spin_lock_saveirq(&jazz_dma_lock, flags);
+	spin_lock_irqsave(&jazz_dma_lock, flags);
 
 	/*
 	 * Find free chunk
@@ -120,7 +120,7 @@ unsigned long vdma_alloc(unsigned long p
 		       first < VDMA_PGTBL_ENTRIES) first++;
 		if (first + pages > VDMA_PGTBL_ENTRIES) {
 			/* nothing free */
-			spin_unlock_restoreirq(&jazz_dma_lock, flags);
+			spin_unlock_irqrestore(&jazz_dma_lock, flags);
 			return VDMA_ERROR;
 		}
 
@@ -167,7 +167,7 @@ unsigned long vdma_alloc(unsigned long p
 		printk("\n");
 	}
 
-	spin_unlock_restoreirq(&jazz_dma_lock, flags);
+	spin_unlock_irqrestore(&jazz_dma_lock, flags);
 
 	return laddr;
 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/kernel/Makefile linux-2.4.29-pre3/arch/mips/kernel/Makefile
--- linux-2.4.28/arch/mips/kernel/Makefile	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/kernel/Makefile	2004-12-22 16:06:31.046578144 +0000
@@ -12,11 +12,11 @@ all:	kernel.o head.o init_task.o
 
 O_TARGET := kernel.o
 
-export-objs	= irq.o mips_ksyms.o pci-dma.o setup.o semaphore.o smp.o
+export-objs	= irq.o mips_ksyms.o pci-dma.o setup.o semaphore.o smp.o time.o
 
 obj-y		+= branch.o cpu-probe.o irq.o process.o signal.o entry.o \
 		   traps.o ptrace.o reset.o semaphore.o setup.o syscall.o \
-		   sysmips.o ipc.o scall_o32.o unaligned.o
+		   sysmips.o ipc.o scall_o32.o time.o unaligned.o
 
 obj-$(CONFIG_MODULES)		+= mips_ksyms.o
 
@@ -42,12 +42,7 @@ obj-$(CONFIG_SMP)		+= smp.o
 
 obj-$(CONFIG_I8259)		+= i8259.o
 obj-$(CONFIG_IRQ_CPU)		+= irq_cpu.o
-
-# transition from old time.c to new time.c
-# some boards uses old-time.c, some use time.c, and some use their own ones
-export-objs			+= old-time.o time.o
-obj-$(CONFIG_OLD_TIME_C)	+= old-time.o
-obj-$(CONFIG_NEW_TIME_C)	+= time.o
+obj-$(CONFIG_IRQ_CPU_RM7K)	+= irq-rm7000.o
 
 obj-$(CONFIG_BINFMT_IRIX)	+= irixelf.o irixioctl.o irixsig.o sysirix.o \
 				   irixinv.o
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/kernel/cpu-probe.c linux-2.4.29-pre3/arch/mips/kernel/cpu-probe.c
--- linux-2.4.28/arch/mips/kernel/cpu-probe.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/kernel/cpu-probe.c	2004-12-22 16:06:36.715716304 +0000
@@ -43,14 +43,21 @@ extern void (*au1k_wait_ptr)(void);
 void au1k_wait(void)
 {
 #ifdef CONFIG_PM
+	unsigned long addr;
 	/* using the wait instruction makes CP0 counter unusable */
-	__asm__(".set\tmips3\n\t"
+	__asm__("la %0,au1k_wait\n\t"
+		".set mips3\n\t"
+		"cache 0x14,0(%0)\n\t"
+		"cache 0x14,32(%0)\n\t"
+		"sync\n\t"
+		"nop\n\t"
 		"wait\n\t"
 		"nop\n\t"
 		"nop\n\t"
 		"nop\n\t"
 		"nop\n\t"
-		".set\tmips0");
+		".set mips0\n\t"
+		: : "r" (addr));
 #else
 	__asm__("nop\n\t"
 		"nop");
@@ -81,7 +88,7 @@ static inline void check_wait(void)
 	case CPU_R5000:
 	case CPU_NEVADA:
 	case CPU_RM7000:
-/*	case CPU_RM9000: */
+	case CPU_RM9000:
 	case CPU_TX49XX:
 	case CPU_4KC:
 	case CPU_4KEC:
@@ -97,6 +104,7 @@ static inline void check_wait(void)
 	case CPU_AU1000:
 	case CPU_AU1100:
 	case CPU_AU1500:
+	case CPU_AU1550:
 		if (au1k_wait_ptr != NULL) {
 			cpu_wait = au1k_wait_ptr;
 			printk(" available.\n");
@@ -170,8 +178,7 @@ static inline void cpu_probe_legacy(stru
 	case PRID_IMP_R2000:
 		c->cputype = CPU_R2000;
 		c->isa_level = MIPS_CPU_ISA_I;
-		c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX |
-		             MIPS_CPU_LLSC;
+		c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX;
 		if (__cpu_has_fpu())
 			c->options |= MIPS_CPU_FPU;
 		c->tlbsize = 64;
@@ -185,17 +192,24 @@ static inline void cpu_probe_legacy(stru
 		else
 			c->cputype = CPU_R3000;
 		c->isa_level = MIPS_CPU_ISA_I;
-		c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX |
-		             MIPS_CPU_LLSC;
+		c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX; 
 		if (__cpu_has_fpu())
 			c->options |= MIPS_CPU_FPU;
 		c->tlbsize = 64;
 		break;
 	case PRID_IMP_R4000:
-		if ((c->processor_id & 0xff) >= PRID_REV_R4400)
-			c->cputype = CPU_R4400SC;
-		else
-			c->cputype = CPU_R4000SC;
+		if (read_c0_config() & CONF_SC) {
+			if ((c->processor_id & 0xff) >= PRID_REV_R4400)
+				c->cputype = CPU_R4400PC;
+			else
+				c->cputype = CPU_R4000PC;
+		} else {
+			if ((c->processor_id & 0xff) >= PRID_REV_R4400)
+				c->cputype = CPU_R4400SC;
+			else
+				c->cputype = CPU_R4000SC;
+		}
+
 		c->isa_level = MIPS_CPU_ISA_III;
 		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
 		             MIPS_CPU_WATCH | MIPS_CPU_VCE |
@@ -476,6 +490,7 @@ static inline void cpu_probe_mips(struct
 static inline void cpu_probe_alchemy(struct cpuinfo_mips *c)
 {
 	decode_config1(c);
+	c->options |= MIPS_CPU_PREFETCH;
 	switch (c->processor_id & 0xff00) {
 	case PRID_IMP_AU1_REV1:
 	case PRID_IMP_AU1_REV2:
@@ -492,6 +507,9 @@ static inline void cpu_probe_alchemy(str
 		case 3:
 			c->cputype = CPU_AU1550;
 			break;
+		case 4:
+			c->cputype = CPU_AU1200;
+			break;
 		default:
 			panic("Unknown Au Core!");
 			break;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/kernel/gdb-low.S linux-2.4.29-pre3/arch/mips/kernel/gdb-low.S
--- linux-2.4.28/arch/mips/kernel/gdb-low.S	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/kernel/gdb-low.S	2004-12-22 16:05:58.773484400 +0000
@@ -283,7 +283,7 @@
 		lw	v0,GDB_FR_HI(sp)
 		lw	v1,GDB_FR_LO(sp)
 		mthi	v0
-		mtlo	v0
+		mtlo	v1
 		lw	ra,GDB_FR_REG31(sp)
 		lw	fp,GDB_FR_REG30(sp)
 		lw	gp,GDB_FR_REG28(sp)
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/kernel/head.S linux-2.4.29-pre3/arch/mips/kernel/head.S
--- linux-2.4.28/arch/mips/kernel/head.S	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/kernel/head.S	2004-12-22 16:07:09.188779648 +0000
@@ -63,7 +63,7 @@
 		nop
 
 		j	cache_parity_error
-		nop
+		 nop
 		END(except_vec2_generic)
 
 		.set	at
@@ -105,7 +105,7 @@
 		sll	k0, k0, 30	# Check for SDBBP.
 		bgez	k0, ejtag_return
 
-		la	k0, ejtag_debug_buffer
+		 la	k0, ejtag_debug_buffer
 		sw	k1, 0(k0)
 		SAVE_ALL
 		jal	ejtag_exception_handler
@@ -202,7 +202,7 @@ ejtag_return:
 		and	t0, t1
 		or	t0, (ST0_CU0);
 		jal	start_secondary
-		mtc0	t0, CP0_STATUS
+		 mtc0	t0, CP0_STATUS
 		.set pop
 		END(smp_bootstrap)
 #endif
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/kernel/irq-rm7000.c linux-2.4.29-pre3/arch/mips/kernel/irq-rm7000.c
--- linux-2.4.28/arch/mips/kernel/irq-rm7000.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/kernel/irq-rm7000.c	2004-12-22 16:05:33.174376056 +0000
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2003 Ralf Baechle
+ *
+ * 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.
+ *
+ * Handler for RM7000 extended interrupts.  These are a non-standard
+ * feature so we handle them separately from standard interrupts.
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+static int irq_base;
+
+static inline void unmask_rm7k_irq(unsigned int irq)
+{
+	set_c0_intcontrol(0x100 << (irq - irq_base));
+}
+
+static inline void mask_rm7k_irq(unsigned int irq)
+{
+	clear_c0_intcontrol(0x100 << (irq - irq_base));
+}
+
+static inline void rm7k_cpu_irq_enable(unsigned int irq)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	unmask_rm7k_irq(irq);
+	local_irq_restore(flags);
+}
+
+static void rm7k_cpu_irq_disable(unsigned int irq)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	mask_rm7k_irq(irq);
+	local_irq_restore(flags);
+}
+
+static unsigned int rm7k_cpu_irq_startup(unsigned int irq)
+{
+	rm7k_cpu_irq_enable(irq);
+
+	return 0;
+}
+
+#define	rm7k_cpu_irq_shutdown	rm7k_cpu_irq_disable
+
+/*
+ * While we ack the interrupt interrupts are disabled and thus we don't need
+ * to deal with concurrency issues.  Same for rm7k_cpu_irq_end.
+ */
+static void rm7k_cpu_irq_ack(unsigned int irq)
+{
+	mask_rm7k_irq(irq);
+}
+
+static void rm7k_cpu_irq_end(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		unmask_rm7k_irq(irq);
+}
+
+static hw_irq_controller rm7k_irq_controller = {
+	"RM7000",
+	rm7k_cpu_irq_startup,
+	rm7k_cpu_irq_shutdown,
+	rm7k_cpu_irq_enable,
+	rm7k_cpu_irq_disable,
+	rm7k_cpu_irq_ack,
+	rm7k_cpu_irq_end,
+};
+
+void __init rm7k_cpu_irq_init(int base)
+{
+	int i;
+
+	clear_c0_intcontrol(0x00000f00);		/* Mask all */
+
+	for (i = base; i < base + 4; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = NULL;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &rm7k_irq_controller;
+	}
+
+	irq_base = base;
+}
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/kernel/irq_cpu.c linux-2.4.29-pre3/arch/mips/kernel/irq_cpu.c
--- linux-2.4.28/arch/mips/kernel/irq_cpu.c	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/kernel/irq_cpu.c	2004-12-22 16:06:05.949393496 +0000
@@ -2,6 +2,8 @@
  * Copyright 2001 MontaVista Software Inc.
  * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
  *
+ * Copyright (C) 2001 Ralf Baechle
+ *
  * This file define the irq handler for MIPS CPU interrupts.
  *
  * This program is free software; you can redistribute  it and/or modify it
@@ -13,9 +15,12 @@
 /*
  * Almost all MIPS CPUs define 8 interrupt sources.  They are typically
  * level triggered (i.e., cannot be cleared from CPU; must be cleared from
- * device).  The first two are software interrupts.  The last one is
- * usually the CPU timer interrupt if counter register is present or, for
- * CPUs with an external FPU, by convention it's the FPU exception interrupt.
+ * device).  The first two are software interrupts which we don't really
+ * use or support.  The last one is usually the CPU timer interrupt if
+ * counter register is present or, for CPUs with an external FPU, by
+ * convention it's the FPU exception interrupt.
+ *
+ * Don't even think about using this on SMP.  You have been warned.
  *
  * This file exports one global function:
  *	void mips_cpu_irq_init(int irq_base);
@@ -26,18 +31,37 @@
 
 #include <asm/irq_cpu.h>
 #include <asm/mipsregs.h>
+#include <asm/system.h>
+
+static int mips_cpu_irq_base;
+
+static inline void unmask_mips_irq(unsigned int irq)
+{
+	clear_c0_cause(0x100 << (irq - mips_cpu_irq_base));
+	set_c0_status(0x100 << (irq - mips_cpu_irq_base));
+}
 
-static int mips_cpu_irq_base = -1;
+static inline void mask_mips_irq(unsigned int irq)
+{
+	clear_c0_status(0x100 << (irq - mips_cpu_irq_base));
+}
 
-static void mips_cpu_irq_enable(unsigned int irq)
+static inline void mips_cpu_irq_enable(unsigned int irq)
 {
-	clear_c0_cause( 1 << (irq - mips_cpu_irq_base + 8));
-	set_c0_status(1 << (irq - mips_cpu_irq_base + 8));
+	unsigned long flags;
+
+	local_irq_save(flags);
+	unmask_mips_irq(irq);
+	local_irq_restore(flags);
 }
 
 static void mips_cpu_irq_disable(unsigned int irq)
 {
-	clear_c0_status(1 << (irq - mips_cpu_irq_base + 8));
+	unsigned long flags;
+
+	local_irq_save(flags);
+	mask_mips_irq(irq);
+	local_irq_restore(flags);
 }
 
 static unsigned int mips_cpu_irq_startup(unsigned int irq)
@@ -49,21 +73,22 @@ static unsigned int mips_cpu_irq_startup
 
 #define	mips_cpu_irq_shutdown	mips_cpu_irq_disable
 
+/*
+ * While we ack the interrupt interrupts are disabled and thus we don't need
+ * to deal with concurrency issues.  Same for mips_cpu_irq_end.
+ */
 static void mips_cpu_irq_ack(unsigned int irq)
 {
-	/* although we attempt to clear the IP bit in cause register, I think
-	 * usually it is cleared by device (irq source)
-	 */
-	clear_c0_cause(1 << (irq - mips_cpu_irq_base + 8));
+	/* Only necessary for soft interrupts */
+	clear_c0_cause(0x100 << (irq - mips_cpu_irq_base));
 
-	/* disable this interrupt - so that we safe proceed to the handler */
-	mips_cpu_irq_disable(irq);
+	mask_mips_irq(irq);
 }
 
 static void mips_cpu_irq_end(unsigned int irq)
 {
 	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
-		mips_cpu_irq_enable(irq);
+		unmask_mips_irq(irq);
 }
 
 static hw_irq_controller mips_cpu_irq_controller = {
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/kernel/old-time.c linux-2.4.29-pre3/arch/mips/kernel/old-time.c
--- linux-2.4.28/arch/mips/kernel/old-time.c	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/kernel/old-time.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,521 +0,0 @@
-/*
- * Copyright (C) 1991, 1992, 1995  Linus Torvalds
- * Copyright (C) 1996 - 2000  Ralf Baechle
- * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
- *
- * Don't use.  Deprecated.  Dead meat.
- */
-#include <linux/config.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
-
-#include <asm/bootinfo.h>
-#include <asm/cpu.h>
-#include <asm/mipsregs.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#include <linux/mc146818rtc.h>
-#include <linux/timex.h>
-
-extern volatile unsigned long wall_jiffies;
-unsigned long r4k_interval;
-extern rwlock_t xtime_lock;
-
-/*
- * Change this if you have some constant time drift
- */
-/* This is the value for the PC-style PICs. */
-/* #define USECS_PER_JIFFY (1000020/HZ) */
-
-/* This is for machines which generate the exact clock. */
-#define USECS_PER_JIFFY (1000000/HZ)
-
-/* Cycle counter value at the previous timer interrupt.. */
-
-static unsigned int timerhi, timerlo;
-
-/*
- * On MIPS only R4000 and better have a cycle counter.
- *
- * FIXME: Does playing with the RP bit in c0_status interfere with this code?
- */
-static unsigned long do_fast_gettimeoffset(void)
-{
-	u32 count;
-	unsigned long res, tmp;
-
-	/* Last jiffy when do_fast_gettimeoffset() was called. */
-	static unsigned long last_jiffies;
-	unsigned long quotient;
-
-	/*
-	 * Cached "1/(clocks per usec)*2^32" value.
-	 * It has to be recalculated once each jiffy.
-	 */
-	static unsigned long cached_quotient;
-
-	tmp = jiffies;
-
-	quotient = cached_quotient;
-
-	if (tmp && last_jiffies != tmp) {
-		last_jiffies = tmp;
-		__asm__(".set\tnoreorder\n\t"
-			".set\tnoat\n\t"
-			".set\tmips3\n\t"
-			"lwu\t%0,%2\n\t"
-			"dsll32\t$1,%1,0\n\t"
-			"or\t$1,$1,%0\n\t"
-			"ddivu\t$0,$1,%3\n\t"
-			"mflo\t$1\n\t"
-			"dsll32\t%0,%4,0\n\t"
-			"nop\n\t"
-			"ddivu\t$0,%0,$1\n\t"
-			"mflo\t%0\n\t"
-			".set\tmips0\n\t"
-			".set\tat\n\t"
-			".set\treorder"
-			:"=&r" (quotient)
-			:"r" (timerhi),
-			 "m" (timerlo),
-			 "r" (tmp),
-			 "r" (USECS_PER_JIFFY));
-		cached_quotient = quotient;
-	}
-
-	/* Get last timer tick in absolute kernel time */
-	count = read_c0_count();
-
-	/* .. relative to previous jiffy (32 bits is enough) */
-	count -= timerlo;
-
-	__asm__("multu\t%1,%2\n\t"
-		"mfhi\t%0"
-		:"=r" (res)
-		:"r" (count),
-		 "r" (quotient));
-
-	/*
- 	 * Due to possible jiffies inconsistencies, we need to check
-	 * the result so that we'll get a timer that is monotonic.
-	 */
-	if (res >= USECS_PER_JIFFY)
-		res = USECS_PER_JIFFY-1;
-
-	return res;
-}
-
-/* This function must be called with interrupts disabled
- * It was inspired by Steve McCanne's microtime-i386 for BSD.  -- jrs
- *
- * However, the pc-audio speaker driver changes the divisor so that
- * it gets interrupted rather more often - it loads 64 into the
- * counter rather than 11932! This has an adverse impact on
- * do_gettimeoffset() -- it stops working! What is also not
- * good is that the interval that our timer function gets called
- * is no longer 10.0002 ms, but 9.9767 ms. To get around this
- * would require using a different timing source. Maybe someone
- * could use the RTC - I know that this can interrupt at frequencies
- * ranging from 8192Hz to 2Hz. If I had the energy, I'd somehow fix
- * it so that at startup, the timer code in sched.c would select
- * using either the RTC or the 8253 timer. The decision would be
- * based on whether there was any other device around that needed
- * to trample on the 8253. I'd set up the RTC to interrupt at 1024 Hz,
- * and then do some jiggery to have a version of do_timer that
- * advanced the clock by 1/1024 s. Every time that reached over 1/100
- * of a second, then do all the old code. If the time was kept correct
- * then do_gettimeoffset could just return 0 - there is no low order
- * divider that can be accessed.
- *
- * Ideally, you would be able to use the RTC for the speaker driver,
- * but it appears that the speaker driver really needs interrupt more
- * often than every 120 us or so.
- *
- * Anyway, this needs more thought....		pjsg (1993-08-28)
- *
- * If you are really that interested, you should be reading
- * comp.protocols.time.ntp!
- */
-
-#define TICK_SIZE tick
-
-static unsigned long do_slow_gettimeoffset(void)
-{
-	int count;
-
-	static int count_p = LATCH;    /* for the first call after boot */
-	static unsigned long jiffies_p;
-
-	/*
-	 * cache volatile jiffies temporarily; we have IRQs turned off.
-	 */
-	unsigned long jiffies_t;
-
-	/* timer count may underflow right here */
-	outb_p(0x00, 0x43);	/* latch the count ASAP */
-
-	count = inb_p(0x40);	/* read the latched count */
-
-	/*
-	 * We do this guaranteed double memory access instead of a _p
-	 * postfix in the previous port access. Wheee, hackady hack
-	 */
-	jiffies_t = jiffies;
-
-	count |= inb_p(0x40) << 8;
-
-	/*
-	 * avoiding timer inconsistencies (they are rare, but they happen)...
-	 * there are two kinds of problems that must be avoided here:
-	 *  1. the timer counter underflows
-	 *  2. hardware problem with the timer, not giving us continuous time,
-	 *     the counter does small "jumps" upwards on some Pentium systems,
-	 *     (see c't 95/10 page 335 for Neptun bug.)
-	 */
-
-	if( jiffies_t == jiffies_p ) {
-		if( count > count_p ) {
-			/* the nutcase */
-
-			outb_p(0x0A, 0x20);
-
-			/* assumption about timer being IRQ1 */
-			if (inb(0x20) & 0x01) {
-				/*
-				 * We cannot detect lost timer interrupts ...
-				 * well, that's why we call them lost, don't we? :)
-				 * [hmm, on the Pentium and Alpha we can ... sort of]
-				 */
-				count -= LATCH;
-			} else {
-				printk("do_slow_gettimeoffset(): hardware timer problem?\n");
-			}
-		}
-	} else
-		jiffies_p = jiffies_t;
-
-	count_p = count;
-
-	count = ((LATCH-1) - count) * TICK_SIZE;
-	count = (count + LATCH/2) / LATCH;
-
-	return count;
-}
-
-static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset;
-
-/*
- * This version of gettimeofday has near microsecond resolution.
- */
-void do_gettimeofday(struct timeval *tv)
-{
-	unsigned long flags;
-
-	read_lock_irqsave (&xtime_lock, flags);
-	*tv = xtime;
-	tv->tv_usec += do_gettimeoffset();
-
-	/*
-	 * xtime is atomically updated in timer_bh. jiffies - wall_jiffies
-	 * is nonzero if the timer bottom half hasnt executed yet.
-	 */
-	if (jiffies - wall_jiffies)
-		tv->tv_usec += USECS_PER_JIFFY;
-
-	read_unlock_irqrestore (&xtime_lock, flags);
-
-	if (tv->tv_usec >= 1000000) {
-		tv->tv_usec -= 1000000;
-		tv->tv_sec++;
-	}
-}
-
-void do_settimeofday(struct timeval *tv)
-{
-	write_lock_irq (&xtime_lock);
-
-	/* This is revolting. We need to set the xtime.tv_usec
-	 * correctly. However, the value in this location is
-	 * is value at the last tick.
-	 * Discover what correction gettimeofday
-	 * would have done, and then undo it!
-	 */
-	tv->tv_usec -= do_gettimeoffset();
-
-	if (tv->tv_usec < 0) {
-		tv->tv_usec += 1000000;
-		tv->tv_sec--;
-	}
-
-	xtime = *tv;
-	time_adjust = 0;		/* stop active adjtime() */
-	time_status |= STA_UNSYNC;
-	time_maxerror = NTP_PHASE_LIMIT;
-	time_esterror = NTP_PHASE_LIMIT;
-
-	write_unlock_irq (&xtime_lock);
-}
-
-/*
- * In order to set the CMOS clock precisely, set_rtc_mmss has to be
- * called 500 ms after the second nowtime has started, because when
- * nowtime is written into the registers of the CMOS clock, it will
- * jump to the next second precisely 500 ms later. Check the Motorola
- * MC146818A or Dallas DS12887 data sheet for details.
- *
- * BUG: This routine does not handle hour overflow properly; it just
- *      sets the minutes. Usually you won't notice until after reboot!
- */
-static int set_rtc_mmss(unsigned long nowtime)
-{
-	int retval = 0;
-	int real_seconds, real_minutes, cmos_minutes;
-	unsigned char save_control, save_freq_select;
-
-	save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
-	CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
-
-	save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
-	CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
-
-	cmos_minutes = CMOS_READ(RTC_MINUTES);
-	if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
-		BCD_TO_BIN(cmos_minutes);
-
-	/*
-	 * since we're only adjusting minutes and seconds,
-	 * don't interfere with hour overflow. This avoids
-	 * messing with unknown time zones but requires your
-	 * RTC not to be off by more than 15 minutes
-	 */
-	real_seconds = nowtime % 60;
-	real_minutes = nowtime / 60;
-	if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
-		real_minutes += 30;		/* correct for half hour time zone */
-	real_minutes %= 60;
-
-	if (abs(real_minutes - cmos_minutes) < 30) {
-		if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
-			BIN_TO_BCD(real_seconds);
-			BIN_TO_BCD(real_minutes);
-		}
-		CMOS_WRITE(real_seconds,RTC_SECONDS);
-		CMOS_WRITE(real_minutes,RTC_MINUTES);
-	} else {
-		printk(KERN_WARNING
-		       "set_rtc_mmss: can't update from %d to %d\n",
-		       cmos_minutes, real_minutes);
- 		retval = -1;
-	}
-
-	/* The following flags have to be released exactly in this order,
-	 * otherwise the DS12887 (popular MC146818A clone with integrated
-	 * battery and quartz) will not reset the oscillator and will not
-	 * update precisely 500 ms later. You won't find this mentioned in
-	 * the Dallas Semiconductor data sheets, but who believes data
-	 * sheets anyway ...                           -- Markus Kuhn
-	 */
-	CMOS_WRITE(save_control, RTC_CONTROL);
-	CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
-
-	return retval;
-}
-
-/* last time the cmos clock got updated */
-static long last_rtc_update;
-
-/*
- * timer_interrupt() needs to keep up the real-time clock,
- * as well as call the "do_timer()" routine every clocktick
- */
-static void inline
-timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
-{
-#ifdef CONFIG_DDB5074
-	static unsigned cnt, period, dist;
-
-	if (cnt == 0 || cnt == dist)
-	    ddb5074_led_d2(1);
-	else if (cnt == 7 || cnt == dist+7)
-	    ddb5074_led_d2(0);
-
-	if (++cnt > period) {
-	    cnt = 0;
-	    /* The hyperbolic function below modifies the heartbeat period
-	     * length in dependency of the current (5min) load. It goes
-	     * through the points f(0)=126, f(1)=86, f(5)=51,
-	     * f(inf)->30. */
-	     period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
-	     dist = period / 4;
-	}
-#endif
-	if(!user_mode(regs)) {
-		if (prof_buffer && current->pid) {
-			extern int _stext;
-			unsigned long pc = regs->cp0_epc;
-
-			pc -= (unsigned long) &_stext;
-			pc >>= prof_shift;
-			/*
-			 * Dont ignore out-of-bounds pc values silently,
-			 * put them into the last histogram slot, so if
-			 * present, they will show up as a sharp peak.
-			 */
-			if (pc > prof_len-1)
-				pc = prof_len-1;
-			atomic_inc((atomic_t *)&prof_buffer[pc]);
-		}
-	}
-	do_timer(regs);
-
-	/*
-	 * If we have an externally synchronized Linux clock, then update
-	 * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
-	 * called as close as possible to 500 ms before the new second starts.
-	 */
-	read_lock (&xtime_lock);
-	if ((time_status & STA_UNSYNC) == 0 &&
-	    xtime.tv_sec > last_rtc_update + 660 &&
-	    xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&
-	    xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) {
-		if (set_rtc_mmss(xtime.tv_sec) == 0)
-			last_rtc_update = xtime.tv_sec;
-		else
-			/* do it again in 60 s */
-			last_rtc_update = xtime.tv_sec - 600;
-	}
-
-	/*
-	 * As we return to user mode fire off the other CPU schedulers.. this
-	 * is basically because we don't yet share IRQ's around. This message
-	 * is rigged to be safe on the 386 - basically it's a hack, so don't
-	 * look closely for now..
-	 */
-	/*smp_message_pass(MSG_ALL_BUT_SELF, MSG_RESCHEDULE, 0L, 0); */
-	read_unlock (&xtime_lock);
-}
-
-static inline void
-r4k_timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
-{
-	unsigned int count;
-
-	/*
-	 * The cycle counter is only 32 bit which is good for about
-	 * a minute at current count rates of upto 150MHz or so.
-	 */
-	count = read_c0_count();
-	timerhi += (count < timerlo);	/* Wrap around */
-	timerlo = count;
-
-#ifdef CONFIG_SGI_IP22
-	/* Since we don't get anything but r4k timer interrupts, we need to
-	 * set this up so that we'll get one next time. Fortunately since we
-	 * have timerhi/timerlo, we don't care so much if we miss one. So
-	 * we need only ask for the next in r4k_interval counts. On other
-	 * archs we have a real timer, so we don't want this.
-	 */
-	write_c0_compare(
-				  (unsigned long) (count + r4k_interval));
-        kstat.irqs[0][irq]++;
-#endif
-
-	timer_interrupt(irq, dev_id, regs);
-
-	if (!jiffies)
-	{
-		/*
-		 * If jiffies has overflowed in this timer_interrupt we must
-		 * update the timer[hi]/[lo] to make do_fast_gettimeoffset()
-		 * quotient calc still valid. -arca
-		 */
-		timerhi = timerlo = 0;
-	}
-}
-
-void indy_r4k_timer_interrupt (struct pt_regs *regs)
-{
-	int cpu = smp_processor_id();
-	int irq = 7;
-
-	irq_enter(cpu, irq);
-	r4k_timer_interrupt(irq, NULL, regs);
-	irq_exit(cpu, irq);
-
-	if (softirq_pending(cpu))
-		do_softirq();
-}
-
-struct irqaction irq0  = { timer_interrupt, SA_INTERRUPT, 0,
-                                  "timer", NULL, NULL};
-
-
-void (*board_time_init)(struct irqaction *irq);
-
-void __init time_init(void)
-{
-	unsigned int epoch = 0, year, mon, day, hour, min, sec;
-	int i;
-
-	/* The Linux interpretation of the CMOS clock register contents:
-	 * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
-	 * RTC registers show the second which has precisely just started.
-	 * Let's hope other operating systems interpret the RTC the same way.
-	 */
-	/* read RTC exactly on falling edge of update flag */
-	for (i = 0 ; i < 1000000 ; i++)	/* may take up to 1 second... */
-		if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
-			break;
-	for (i = 0 ; i < 1000000 ; i++)	/* must try at least 2.228 ms */
-		if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
-			break;
-	do { /* Isn't this overkill ? UIP above should guarantee consistency */
-		sec = CMOS_READ(RTC_SECONDS);
-		min = CMOS_READ(RTC_MINUTES);
-		hour = CMOS_READ(RTC_HOURS);
-		day = CMOS_READ(RTC_DAY_OF_MONTH);
-		mon = CMOS_READ(RTC_MONTH);
-		year = CMOS_READ(RTC_YEAR);
-	} while (sec != CMOS_READ(RTC_SECONDS));
-	if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
-	  {
-	    BCD_TO_BIN(sec);
-	    BCD_TO_BIN(min);
-	    BCD_TO_BIN(hour);
-	    BCD_TO_BIN(day);
-	    BCD_TO_BIN(mon);
-	    BCD_TO_BIN(year);
-	  }
-
-	/* Attempt to guess the epoch.  This is the same heuristic as in rtc.c so
-	   no stupid things will happen to timekeeping.  Who knows, maybe Ultrix
-  	   also uses 1952 as epoch ...  */
-	if (year > 10 && year < 44) {
-		epoch = 1980;
-	} else if (year < 96) {
-		epoch = 1952;
-	}
-	year += epoch;
-
-	write_lock_irq (&xtime_lock);
-	xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
-	xtime.tv_usec = 0;
-	write_unlock_irq (&xtime_lock);
-
-	if (cpu_has_counter) {
-		write_c0_count(0);
-		do_gettimeoffset = do_fast_gettimeoffset;
-		irq0.handler = r4k_timer_interrupt;
-	}
-
-	board_time_init(&irq0);
-}
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/kernel/proc.c linux-2.4.29-pre3/arch/mips/kernel/proc.c
--- linux-2.4.28/arch/mips/kernel/proc.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/kernel/proc.c	2004-12-22 16:06:02.767877160 +0000
@@ -48,7 +48,6 @@ static const char *cpu_name[] = {
 	[CPU_R4640]	"R4640",
 	[CPU_NEVADA]	"Nevada",
 	[CPU_RM7000]	"RM7000",
-	[CPU_RM9000]	"RM9000",
 	[CPU_R5432]	"R5432",
 	[CPU_4KC]	"MIPS 4Kc",
         [CPU_5KC]	"MIPS 5Kc",
@@ -58,23 +57,27 @@ static const char *cpu_name[] = {
 	[CPU_TX3922]	"TX3922",
 	[CPU_TX3927]	"TX3927",
 	[CPU_AU1000]	"Au1000",
-	[CPU_AU1500]	"Au1500",
 	[CPU_4KEC]	"MIPS 4KEc",
 	[CPU_4KSC]	"MIPS 4KSc",
 	[CPU_VR41XX]	"NEC Vr41xx",
 	[CPU_R5500]	"R5500",
 	[CPU_TX49XX]	"TX49xx",
+	[CPU_AU1500]	"Au1500",
 	[CPU_20KC]	"MIPS 20Kc",
-	[CPU_24K]	"MIPS 24K",
-	[CPU_25KF]	"MIPS 25Kf",
 	[CPU_VR4111]	"NEC VR4111",
 	[CPU_VR4121]	"NEC VR4121",
 	[CPU_VR4122]	"NEC VR4122",
 	[CPU_VR4131]	"NEC VR4131",
-	[CPU_VR4133]	"NEC VR4133",
 	[CPU_VR4181]	"NEC VR4181",
 	[CPU_VR4181A]	"NEC VR4181A",
-	[CPU_SR71000]	"Sandcraft SR71000"
+	[CPU_AU1100]	"Au1100",
+	[CPU_SR71000]	"Sandcraft SR71000",
+	[CPU_RM9000]	"RM9000",
+	[CPU_25KF]	"MIPS 25Kf",
+	[CPU_VR4133]	"NEC VR4133",
+	[CPU_AU1550]	"Au1550",
+	[CPU_24K]	"MIPS 24K",
+	[CPU_AU1200]	"Au1200",
 };
 
 
@@ -116,7 +119,7 @@ static int show_cpuinfo(struct seq_file 
 	              cpu_has_watch ? "yes" : "no");
 
 	sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",
-	        cpu_has_vce ? "%d" : "not available");
+	        cpu_has_vce ? "%u" : "not available");
 	seq_printf(m, fmt, 'D', vced_count);
 	seq_printf(m, fmt, 'I', vcei_count);
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/kernel/scall_o32.S linux-2.4.29-pre3/arch/mips/kernel/scall_o32.S
--- linux-2.4.28/arch/mips/kernel/scall_o32.S	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/kernel/scall_o32.S	2004-12-22 16:07:19.689183344 +0000
@@ -31,8 +31,8 @@ NESTED(handle_sys, PT_SIZE, sp)
 
 	sltiu	t0, v0, MAX_SYSCALL_NO + 1 # check syscall number
 	addiu	t1, 4			# skip to next instruction
-	beqz	t0, illegal_syscall
 	sw	t1, PT_EPC(sp)
+	beqz	t0, illegal_syscall
 
 	/* XXX Put both in one cacheline, should save a bit. */
 	sll	t0, v0, 2
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/kernel/semaphore.c linux-2.4.29-pre3/arch/mips/kernel/semaphore.c
--- linux-2.4.28/arch/mips/kernel/semaphore.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/kernel/semaphore.c	2004-12-22 16:07:06.021261184 +0000
@@ -8,7 +8,7 @@
 #include <linux/module.h>
 #include <linux/sched.h>
 
-#ifdef CONFIG_CPU_HAS_LLDSCD
+#ifndef CONFIG_CPU_HAS_LLDSCD
 /*
  * On machines without lld/scd we need a spinlock to make the manipulation of
  * sem->count and sem->waking atomic.  Scalability isn't an issue because
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/kernel/setup.c linux-2.4.29-pre3/arch/mips/kernel/setup.c
--- linux-2.4.28/arch/mips/kernel/setup.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/kernel/setup.c	2004-12-22 16:05:54.429144840 +0000
@@ -40,6 +40,7 @@
 #include <asm/system.h>
 
 struct cpuinfo_mips cpu_data[NR_CPUS];
+EXPORT_SYMBOL(cpu_data);
 
 /*
  * There are several bus types available for MIPS machines.  "RISC PC"
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/kernel/signal.c linux-2.4.29-pre3/arch/mips/kernel/signal.c
--- linux-2.4.28/arch/mips/kernel/signal.c	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/kernel/signal.c	2004-12-22 16:07:19.691183040 +0000
@@ -382,7 +382,7 @@ static inline void * get_sigframe(struct
  	sp -= 32;
 
 	/* This is the X/Open sanctioned signal stack switching.  */
-	if ((ka->sa.sa_flags & SA_ONSTACK) && ! on_sig_stack(sp))
+	if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
                 sp = current->sas_ss_sp + current->sas_ss_size;
 
 	return (void *)((sp - frame_size) & ALMASK);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/kernel/smp.c linux-2.4.29-pre3/arch/mips/kernel/smp.c
--- linux-2.4.28/arch/mips/kernel/smp.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/kernel/smp.c	2004-12-22 16:05:53.578274192 +0000
@@ -52,6 +52,9 @@ int __cpu_number_map[NR_CPUS];
 int __cpu_logical_map[NR_CPUS];
 cycles_t cacheflush_time;
 
+EXPORT_SYMBOL(__cpu_number_map);
+EXPORT_SYMBOL(__cpu_logical_map);
+
 void __init smp_callin(void)
 {
 #if 0
@@ -110,6 +113,7 @@ int smp_call_function (void (*func) (voi
 
 	spin_lock(&smp_call_lock);
 	call_data = &data;
+	wmb();
 
 	/* Send a message to all other CPUs and wait for them to respond */
 	for (i = 0; i < smp_num_cpus; i++)
@@ -283,7 +287,6 @@ void flush_tlb_page(struct vm_area_struc
 
 EXPORT_SYMBOL(smp_num_cpus);
 EXPORT_SYMBOL(flush_tlb_page);
-EXPORT_SYMBOL(cpu_data);
 EXPORT_SYMBOL(synchronize_irq);
 EXPORT_SYMBOL(kernel_flag);
 EXPORT_SYMBOL(__global_sti);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/kernel/syscall.c linux-2.4.29-pre3/arch/mips/kernel/syscall.c
--- linux-2.4.28/arch/mips/kernel/syscall.c	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/kernel/syscall.c	2004-12-22 16:07:21.022980576 +0000
@@ -39,7 +39,7 @@ extern asmlinkage int (*do_syscalls)(str
 extern syscall_t sys_call_table[];
 extern unsigned char sys_narg_table[];
 
-asmlinkage int sys_pipe(struct pt_regs regs)
+asmlinkage int sys_pipe(volatile struct pt_regs regs)
 {
 	int fd[2];
 	int error, res;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/kernel/sysirix.c linux-2.4.29-pre3/arch/mips/kernel/sysirix.c
--- linux-2.4.28/arch/mips/kernel/sysirix.c	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/kernel/sysirix.c	2004-12-22 16:07:38.100384416 +0000
@@ -928,8 +928,8 @@ asmlinkage int irix_getdomainname(char *
 		return error;
 
 	down_read(&uts_sem);
-	if(len > (__NEW_UTS_LEN - 1))
-		len = __NEW_UTS_LEN - 1;
+	if (len > __NEW_UTS_LEN)
+		len = __NEW_UTS_LEN;
 	error = 0;
 	if (copy_to_user(name, system_utsname.domainname, len))
 		error = -EFAULT;
@@ -1712,7 +1712,7 @@ asmlinkage int irix_statvfs64(char *fnam
 
 	printk("[%s:%d] Wheee.. irix_statvfs(%s,%p)\n",
 	       current->comm, current->pid, fname, buf);
-	error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
+	error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs64));
 	if(error)
 		goto out;
 	error = user_path_walk(fname, &nd);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/kernel/time.c linux-2.4.29-pre3/arch/mips/kernel/time.c
--- linux-2.4.28/arch/mips/kernel/time.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/kernel/time.c	2004-12-22 16:06:34.144107248 +0000
@@ -1,7 +1,7 @@
 /*
  * Copyright 2001 MontaVista Software Inc.
  * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
- * Copyright (c) 2003  Maciej W. Rozycki
+ * Copyright (c) 2003, 2004  Maciej W. Rozycki
  *
  * Common time service routines for MIPS machines. See
  * Documentation/mips/time.README.
@@ -26,6 +26,7 @@
 #include <linux/module.h>
 
 #include <asm/bootinfo.h>
+#include <asm/compiler.h>
 #include <asm/cpu.h>
 #include <asm/time.h>
 #include <asm/hardirq.h>
@@ -242,7 +243,7 @@ static unsigned long fixed_rate_gettimeo
 	__asm__("multu	%1,%2"
 		: "=h" (res)
 		: "r" (count), "r" (sll32_usecs_per_cycle)
-		: "lo", "accum");
+		: "lo", GCC_REG_ACCUM);
 
 	/*
 	 * Due to possible jiffies inconsistencies, we need to check
@@ -297,7 +298,7 @@ static unsigned long calibrate_div32_get
 	__asm__("multu  %1,%2"
 		: "=h" (res)
 		: "r" (count), "r" (quotient)
-		: "lo", "accum");
+		: "lo", GCC_REG_ACCUM);
 
 	/*
 	 * Due to possible jiffies inconsistencies, we need to check
@@ -339,7 +340,7 @@ static unsigned long calibrate_div64_get
 				: "r" (timerhi), "m" (timerlo),
 				  "r" (tmp), "r" (USECS_PER_JIFFY),
 				  "r" (USECS_PER_JIFFY_FRAC)
-				: "hi", "lo", "accum");
+				: "hi", "lo", GCC_REG_ACCUM);
 			cached_quotient = quotient;
 		}
 	}
@@ -353,7 +354,7 @@ static unsigned long calibrate_div64_get
 	__asm__("multu	%1,%2"
 		: "=h" (res)
 		: "r" (count), "r" (quotient)
-		: "lo", "accum");
+		: "lo", GCC_REG_ACCUM);
 
 	/*
 	 * Due to possible jiffies inconsistencies, we need to check
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/kernel/traps.c linux-2.4.29-pre3/arch/mips/kernel/traps.c
--- linux-2.4.28/arch/mips/kernel/traps.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/kernel/traps.c	2004-12-22 16:06:31.651486184 +0000
@@ -9,7 +9,7 @@
  * Copyright (C) 1999 Silicon Graphics, Inc.
  * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
  * Copyright (C) 2000, 01 MIPS Technologies, Inc.
- * Copyright (C) 2002, 2003  Maciej W. Rozycki
+ * Copyright (C) 2002, 2003, 2004  Maciej W. Rozycki
  */
 #include <linux/config.h>
 #include <linux/init.h>
@@ -22,6 +22,7 @@
 
 #include <asm/bootinfo.h>
 #include <asm/branch.h>
+#include <asm/break.h>
 #include <asm/cpu.h>
 #include <asm/fpu.h>
 #include <asm/cachectl.h>
@@ -352,7 +353,7 @@ asmlinkage void do_be(struct pt_regs *re
 	int action = MIPS_BE_FATAL;
 
 	if (data && !user_mode(regs))
-		fixup = search_dbe_table(regs->cp0_epc);
+		fixup = search_dbe_table(exception_epc(regs));
 
 	if (fixup)
 		action = MIPS_BE_FIXUP;
@@ -596,9 +597,12 @@ asmlinkage void do_bp(struct pt_regs *re
 	/*
 	 * There is the ancient bug in the MIPS assemblers that the break
 	 * code starts left to bit 16 instead to bit 6 in the opcode.
-	 * Gas is bug-compatible ...
+	 * Gas is bug-compatible, but not always, grrr...
+	 * We handle both cases with a simple heuristics.  --macro
 	 */
-	bcode = ((opcode >> 16) & ((1 << 20) - 1));
+	bcode = ((opcode >> 6) & ((1 << 20) - 1));
+	if (bcode < (1 << 10))
+		bcode <<= 10;
 
 	/*
 	 * (A short test says that IRIX 5.3 sends SIGTRAP for all break
@@ -607,9 +611,9 @@ asmlinkage void do_bp(struct pt_regs *re
 	 * But should we continue the brokenness???  --macro
 	 */
 	switch (bcode) {
-	case 6:
-	case 7:
-		if (bcode == 7)
+	case BRK_OVERFLOW << 10:
+	case BRK_DIVZERO << 10:
+		if (bcode == (BRK_DIVZERO << 10))
 			info.si_code = FPE_INTDIV;
 		else
 			info.si_code = FPE_INTOVF;
@@ -633,7 +637,7 @@ asmlinkage void do_tr(struct pt_regs *re
 
 	/* Immediate versions don't provide a code.  */
 	if (!(opcode & OPCODE))
-		tcode = ((opcode >> 6) & ((1 << 20) - 1));
+		tcode = ((opcode >> 6) & ((1 << 10) - 1));
 
 	/*
 	 * (A short test says that IRIX 5.3 sends SIGTRAP for all trap
@@ -642,9 +646,9 @@ asmlinkage void do_tr(struct pt_regs *re
 	 * But should we continue the brokenness???  --macro
 	 */
 	switch (tcode) {
-	case 6:
-	case 7:
-		if (tcode == 7)
+	case BRK_OVERFLOW:
+	case BRK_DIVZERO:
+		if (tcode == BRK_DIVZERO)
 			info.si_code = FPE_INTDIV;
 		else
 			info.si_code = FPE_INTOVF;
@@ -933,8 +937,7 @@ void __init trap_init(void)
 		memcpy((void *)(KSEG0 + 0x300), &except_vec_ejtag_debug, 0x80);
 
 	/*
-	 * Only some CPUs have the watch exceptions or a dedicated
-	 * interrupt vector.
+	 * Only some CPUs have the watch exceptions.
 	 */
 	if (cpu_has_watch)
 		set_except_vector(23, handle_watch);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/lasat/ds1603.c linux-2.4.29-pre3/arch/mips/lasat/ds1603.c
--- linux-2.4.28/arch/mips/lasat/ds1603.c	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/lasat/ds1603.c	2004-12-22 16:07:19.691183040 +0000
@@ -51,14 +51,14 @@ static void rtc_cycle_clock(unsigned lon
 {
 	data |= ds1603->clk;
 	rtc_reg_write(data);
-	ndelay(250);
+	lasat_ndelay(250);
 	if (ds1603->data_reversed)
 		data &= ~ds1603->data;
 	else
 		data |= ds1603->data;
 	data &= ~ds1603->clk;
 	rtc_reg_write(data);
-	ndelay(250 + ds1603->huge_delay);
+	lasat_ndelay(250 + ds1603->huge_delay);
 }
 
 static void rtc_write_databit(unsigned int bit)
@@ -72,7 +72,7 @@ static void rtc_write_databit(unsigned i
 		data &= ~ds1603->data;
 
 	rtc_reg_write(data);
-	ndelay(50 + ds1603->huge_delay);
+	lasat_ndelay(50 + ds1603->huge_delay);
 	rtc_cycle_clock(data);
 }
 
@@ -125,13 +125,13 @@ static void rtc_init_op(void)
 
 	rtc_reg_write(rtc_reg_read() & ~ds1603->clk);
 
-	ndelay(50);
+	lasat_ndelay(50);
 }
 
 static void rtc_end_op(void)
 {
 	rtc_nrst_low();
-	ndelay(1000);
+	lasat_ndelay(1000);
 }
 
 /* interface */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/lasat/image/Makefile linux-2.4.29-pre3/arch/mips/lasat/image/Makefile
--- linux-2.4.28/arch/mips/lasat/image/Makefile	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/lasat/image/Makefile	2004-12-22 16:05:32.904417096 +0000
@@ -24,12 +24,13 @@ KERNEL_ENTRY = $(shell $(NM) $(KERNEL_IM
 
 LDSCRIPT= -Tromscript.normal
 
-AFLAGS_head.o = -D_kernel_start=0x$(KERNEL_START) \
+HEAD_DEFINES = -D_kernel_start=0x$(KERNEL_START) \
 		-D_kernel_entry=0x$(KERNEL_ENTRY) \
 		-D VERSION="\"$(Version)\"" \
 		-D TIMESTAMP=$(shell date +%s) 
 
-head.o: $(KERNEL_IMAGE)
+head.o: head.S $(KERNEL_IMAGE)
+	$(CC) -fno-pic $(HEAD_DEFINES) -I$(TOPDIR)/include -c -o $@ $<
 
 OBJECTS= head.o kImage.o
 
@@ -44,7 +45,7 @@ rom:	$(OBJECTS)
 	$(LD) $(LDFLAGS) $(LDSCRIPT) -o rom $(OBJECTS) 
 
 %.o: %.gz
-	$(LD) -r -o $@ -b binary $<
+	$(LD) $(LDFLAGS) -r -o $@ -b binary $<
 
 %.gz: %.bin
 	gzip -cf -9 $< > $@
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/ld.script.in linux-2.4.29-pre3/arch/mips/ld.script.in
--- linux-2.4.28/arch/mips/ld.script.in	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/ld.script.in	2004-12-22 16:06:21.276063488 +0000
@@ -10,6 +10,7 @@ SECTIONS
     _ftext = . ;
     *(.text)
     *(.rodata)
+    *(.rodata.*)
     *(.rodata1)
     /* .gnu.warning sections are handled specially by elf32.em.  */
     *(.gnu.warning)
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/lib/dump_tlb.c linux-2.4.29-pre3/arch/mips/lib/dump_tlb.c
--- linux-2.4.28/arch/mips/lib/dump_tlb.c	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/lib/dump_tlb.c	2004-12-22 16:06:49.187820256 +0000
@@ -11,13 +11,13 @@
 #include <linux/string.h>
 
 #include <asm/bootinfo.h>
-#include <asm/cpu.h>
 #include <asm/cachectl.h>
+#include <asm/cpu.h>
 #include <asm/mipsregs.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 
-static inline const char *msg2str(unsigned int mask)
+static inline const char *msk2str(unsigned int mask)
 {
 	switch (mask) {
 	case PM_4K:	return "4kb";
@@ -36,15 +36,15 @@ static inline const char *msg2str(unsign
 
 void dump_tlb(int first, int last)
 {
-	int	i;
 	unsigned int pagemask, c0, c1, asid;
 	unsigned long long entrylo0, entrylo1;
 	unsigned long entryhi;
+	int	i;
 
 	asid = read_c0_entryhi() & 0xff;
 
 	printk("\n");
-	for(i=first;i<=last;i++) {
+	for (i = first; i <= last; i++) {
 		write_c0_index(i);
 		__asm__ __volatile__(
 			".set\tmips3\n\t"
@@ -65,7 +65,7 @@ void dump_tlb(int first, int last)
 			/*
 			 * Only print entries in use
 			 */
-			printk("Index: %2d pgmask=%s ", i, msg2str(pagemask));
+			printk("Index: %2d pgmask=%s ", i, msk2str(pagemask));
 
 			c0 = (entrylo0 >> 3) & 7;
 			c1 = (entrylo1 >> 3) & 7;
@@ -109,8 +109,7 @@ void dump_tlb_wired(void)
 		"nop;nop;nop;nop;nop;nop;nop\n\t"	\
 		".set\treorder");
 
-void
-dump_tlb_addr(unsigned long addr)
+void dump_tlb_addr(unsigned long addr)
 {
 	unsigned long flags, oldpid;
 	int index;
@@ -135,14 +134,12 @@ dump_tlb_addr(unsigned long addr)
 	dump_tlb(index, index);
 }
 
-void
-dump_tlb_nonwired(void)
+void dump_tlb_nonwired(void)
 {
 	dump_tlb(read_c0_wired(), current_cpu_data.tlbsize - 1);
 }
 
-void
-dump_list_process(struct task_struct *t, void *address)
+void dump_list_process(struct task_struct *t, void *address)
 {
 	pgd_t	*page_dir, *pgd;
 	pmd_t	*pmd;
@@ -194,14 +191,12 @@ dump_list_process(struct task_struct *t,
 	printk("\n");
 }
 
-void
-dump_list_current(void *address)
+void dump_list_current(void *address)
 {
 	dump_list_process(current, address);
 }
 
-unsigned int
-vtop(void *address)
+unsigned int vtop(void *address)
 {
 	pgd_t	*pgd;
 	pmd_t	*pmd;
@@ -218,14 +213,14 @@ vtop(void *address)
 	return paddr;
 }
 
-void
-dump16(unsigned long *p)
+void dump16(unsigned long *p)
 {
 	int i;
 
-	for(i=0;i<8;i++)
-	{
-		printk("*%8p = %08lx, ", p, *p); p++;
-		printk("*%8p = %08lx\n", p, *p); p++;
+	for (i = 0; i < 8; i++) {
+		printk("*%08lx == %08lx, ", (unsigned long)p, *p);
+		p++;
+		printk("*%08lx == %08lx\n", (unsigned long)p, *p);
+		p++;
 	}
 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/lib/r3k_dump_tlb.c linux-2.4.29-pre3/arch/mips/lib/r3k_dump_tlb.c
--- linux-2.4.28/arch/mips/lib/r3k_dump_tlb.c	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/lib/r3k_dump_tlb.c	2004-12-22 16:05:43.152859096 +0000
@@ -19,8 +19,7 @@
 
 extern int r3k_have_wired_reg;	/* defined in tlb-r3k.c */
 
-void
-dump_tlb(int first, int last)
+void dump_tlb(int first, int last)
 {
 	int	i;
 	unsigned int asid;
@@ -28,8 +27,7 @@ dump_tlb(int first, int last)
 
 	asid = read_c0_entryhi() & 0xfc0;
 
-	for(i=first;i<=last;i++)
-	{
+	for (i = first; i <= last; i++) {
 		write_c0_index(i<<8);
 		__asm__ __volatile__(
 			".set\tnoreorder\n\t"
@@ -63,14 +61,12 @@ dump_tlb(int first, int last)
 	write_c0_entryhi(asid);
 }
 
-void
-dump_tlb_all(void)
+void dump_tlb_all(void)
 {
 	dump_tlb(0, current_cpu_data.tlbsize - 1);
 }
 
-void
-dump_tlb_wired(void)
+void dump_tlb_wired(void)
 {
 	int wired = r3k_have_wired_reg ? read_c0_wired() : 8;
 
@@ -78,8 +74,7 @@ dump_tlb_wired(void)
 	dump_tlb(0, wired - 1);
 }
 
-void
-dump_tlb_addr(unsigned long addr)
+void dump_tlb_addr(unsigned long addr)
 {
 	unsigned long flags, oldpid;
 	int index;
@@ -101,15 +96,13 @@ dump_tlb_addr(unsigned long addr)
 	dump_tlb(index, index);
 }
 
-void
-dump_tlb_nonwired(void)
+void dump_tlb_nonwired(void)
 {
 	int wired = r3k_have_wired_reg ? read_c0_wired() : 8;
 	dump_tlb(wired, current_cpu_data.tlbsize - 1);
 }
 
-void
-dump_list_process(struct task_struct *t, void *address)
+void dump_list_process(struct task_struct *t, void *address)
 {
 	pgd_t	*page_dir, *pgd;
 	pmd_t	*pmd;
@@ -148,14 +141,12 @@ dump_list_process(struct task_struct *t,
 	printk("\n");
 }
 
-void
-dump_list_current(void *address)
+void dump_list_current(void *address)
 {
 	dump_list_process(current, address);
 }
 
-unsigned int
-vtop(void *address)
+unsigned int vtop(void *address)
 {
 	pgd_t	*pgd;
 	pmd_t	*pmd;
@@ -172,16 +163,14 @@ vtop(void *address)
 	return paddr;
 }
 
-void
-dump16(unsigned long *p)
+void dump16(unsigned long *p)
 {
 	int i;
 
-	for(i=0;i<8;i++)
-	{
-		printk("*%08lx == %08lx, ",
-		       (unsigned long)p, (unsigned long)*p++);
-		printk("*%08lx == %08lx\n",
-		       (unsigned long)p, (unsigned long)*p++);
+	for (i = 0; i < 8; i++) {
+		printk("*%08lx == %08lx, ", (unsigned long)p, *p);
+		p++;
+		printk("*%08lx == %08lx\n", (unsigned long)p, *p);
+		p++;
 	}
 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/lib/strlen_user.S linux-2.4.29-pre3/arch/mips/lib/strlen_user.S
--- linux-2.4.28/arch/mips/lib/strlen_user.S	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/lib/strlen_user.S	2004-12-22 16:07:41.624848616 +0000
@@ -23,18 +23,18 @@
  * Return 0 for error
  */
 LEAF(__strlen_user_asm)
-	lw	v0, THREAD_CURDS($28)	# pointer ok?
-	and	v0, a0
-	bltz	v0, fault
+	LONG_L		v0, THREAD_CURDS($28)	# pointer ok?
+	and		v0, a0
+	bltz		v0, fault
 
 FEXPORT(__strlen_user_nocheck_asm)
-	move	v0, a0
+	move		v0, a0
 1:	EX(lb, t0, (v0), fault)
-	addiu	v0, 1
-	bnez	t0, 1b
-	subu	v0, a0
-	jr	ra
+	addiu		v0, 1
+	bnez		t0, 1b
+	subu		v0, a0
+	jr		ra
 	END(__strlen_user_asm)
 
-fault:	move	v0, zero
-	jr	ra
+fault:	move		v0, zero
+	jr		ra
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/lib/strncpy_user.S linux-2.4.29-pre3/arch/mips/lib/strncpy_user.S
--- linux-2.4.28/arch/mips/lib/strncpy_user.S	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/lib/strncpy_user.S	2004-12-22 16:07:09.866676592 +0000
@@ -28,31 +28,31 @@
  */
 
 LEAF(__strncpy_from_user_asm)
-	lw	v0, THREAD_CURDS($28)	# pointer ok?
-	and	v0, a1
-	bltz	v0, fault
+	LONG_L		v0, THREAD_CURDS($28)	# pointer ok?
+	and		v0, a1
+	bltz		v0, fault
 
-EXPORT(__strncpy_from_user_nocheck_asm)
-	move	v0, zero
-	move	v1, a1
-	.set	noreorder
-1:	EX(lbu,	 t0, (v1), fault)
-	addiu	v1, v1, 1
-	beqz	t0, 2f
-	 sb	t0, (a0)
-	addiu	v0, 1
-	bne	v0, a2, 1b
-	 addiu	a0, 1
-	.set	reorder
-2:	addu	t0, a1, v0
-	xor	t0, a1
-	bltz	t0, fault
-	jr	ra				# return n
+FEXPORT(__strncpy_from_user_nocheck_asm)
+	move		v0, zero
+	move		v1, a1
+	.set		noreorder
+1:	EX(lbu, t0, (v1), fault)
+	PTR_ADDIU	v1, 1
+	beqz		t0, 2f
+	 sb		t0, (a0)
+	PTR_ADDIU	v0, 1
+	bne		v0, a2, 1b
+	 PTR_ADDIU	a0, 1
+	.set		reorder
+2:	PTR_ADDU	t0, a1, v0
+	xor		t0, a1
+	bltz		t0, fault
+	jr		ra			# return n
 	END(__strncpy_from_user_asm)
 
-fault:	li	v0, -EFAULT
-	jr	ra
+fault:	li		v0, -EFAULT
+	jr		ra
 
-	.section __ex_table,"a"
-	PTR	1b, fault
+	.section	__ex_table,"a"
+	PTR		1b, fault
 	.previous
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/lib/strnlen_user.S linux-2.4.29-pre3/arch/mips/lib/strnlen_user.S
--- linux-2.4.28/arch/mips/lib/strnlen_user.S	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/lib/strnlen_user.S	2004-12-22 16:07:31.197433824 +0000
@@ -27,23 +27,22 @@
  *       bytes.  There's nothing secret there ...
  */
 LEAF(__strnlen_user_asm)
-	lw	v0, THREAD_CURDS($28)	# pointer ok?
-	and	v0, a0
-	bltz	v0, fault
+	LONG_L		v0, THREAD_CURDS($28)	# pointer ok?
+	and		v0, a0
+	bltz		v0, fault
 
 FEXPORT(__strnlen_user_nocheck_asm)
-	.type	__strnlen_user_nocheck_asm,@function
-	move	v0, a0
-	addu	a1, a0			# stop pointer
-	.set	noreorder
-1:	beq	v0, a1, 1f		# limit reached?
-	 addiu	v0, 1
-	.set	reorder
+	move		v0, a0
+	PTR_ADDU	a1, a0			# stop pointer
+	.set		noreorder
+1:	beq		v0, a1, 1f		# limit reached?
+	 PTR_ADDIU	v0, 1
+	.set		reorder
 	EX(lb, t0, -1(v0), fault)
-	bnez	t0, 1b
-1:	subu	v0, a0
-	jr	ra
+	bnez		t0, 1b
+1:	PTR_SUBU	v0, a0
+	jr		ra
 	END(__strnlen_user_asm)
 
-fault:	move	v0, zero
-	jr	ra
+fault:	move		v0, zero
+	jr		ra
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/math-emu/cp1emu.c linux-2.4.29-pre3/arch/mips/math-emu/cp1emu.c
--- linux-2.4.28/arch/mips/math-emu/cp1emu.c	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/math-emu/cp1emu.c	2004-12-22 16:07:37.457482152 +0000
@@ -529,9 +529,9 @@ static int cop1Emulate(struct pt_regs *x
 		if (MIPSInst_FUNC(ir) != movc_op)
 			return SIGILL;
 		cond = fpucondbit[MIPSInst_RT(ir) >> 2];
-		if (((ctx->sr & cond) != 0) != ((MIPSInst_RT(ir) & 1) != 0))
-			return 0;
-		xcp->regs[MIPSInst_RD(ir)] = xcp->regs[MIPSInst_RS(ir)];
+		if (((ctx->sr & cond) != 0) == ((MIPSInst_RT(ir) & 1) != 0))
+			xcp->regs[MIPSInst_RD(ir)] =
+				xcp->regs[MIPSInst_RS(ir)];
 		break;
 #endif
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/mm/Makefile linux-2.4.29-pre3/arch/mips/mm/Makefile
--- linux-2.4.28/arch/mips/mm/Makefile	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/mm/Makefile	2004-12-22 16:07:03.573633280 +0000
@@ -10,7 +10,8 @@ USE_STANDARD_AS_RULE := true
 
 O_TARGET := mm.o
 
-export-objs			+= cache.o ioremap.o loadmmu.o remap.o
+export-objs			:= cache.o ioremap.o loadmmu.o remap.o \
+				   tlb-r4k.o tlb-sb1.o
 obj-y				+= cache.o extable.o init.o ioremap.o fault.o \
 				   loadmmu.o
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/mm/c-r3k.c linux-2.4.29-pre3/arch/mips/mm/c-r3k.c
--- linux-2.4.28/arch/mips/mm/c-r3k.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/mm/c-r3k.c	2004-12-22 16:06:53.533159664 +0000
@@ -7,7 +7,7 @@
  * Tx39XX R4k style caches added. HK
  * Copyright (C) 1998, 1999, 2000 Harald Koerfgen
  * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
- * Copyright (C) 2001  Maciej W. Rozycki
+ * Copyright (C) 2001, 2004  Maciej W. Rozycki
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -311,6 +311,9 @@ static void r3k_flush_cache_sigtramp(uns
 
 static void r3k_dma_cache_wback_inv(unsigned long start, unsigned long size)
 {
+	/* Catch bad driver code */
+	BUG_ON(size == 0);
+
 	iob();
 	r3k_flush_dcache_range(start, start + size);
 }
@@ -334,6 +337,8 @@ void __init ld_mmu_r23000(void)
 	_flush_data_cache_page = r3k_flush_data_cache_page;
 
 	_dma_cache_wback_inv = r3k_dma_cache_wback_inv;
+	_dma_cache_wback = r3k_dma_cache_wback_inv;
+	_dma_cache_inv = r3k_dma_cache_wback_inv;
 
 	printk("Primary instruction cache %ldkB, linesize %ld bytes.\n",
 		icache_size >> 10, icache_lsize);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/mm/c-r4k.c linux-2.4.29-pre3/arch/mips/mm/c-r4k.c
--- linux-2.4.28/arch/mips/mm/c-r4k.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/mm/c-r4k.c	2004-12-22 16:07:42.982642200 +0000
@@ -42,12 +42,13 @@ static struct bcache_ops no_sc_ops = {
 
 struct bcache_ops *bcops = &no_sc_ops;
 
+#define cpu_is_r4600_v1_x()	((read_c0_prid() & 0xfffffff0) == 0x2010)
+#define cpu_is_r4600_v2_x()	((read_c0_prid() & 0xfffffff0) == 0x2020)
+
 #define R4600_HIT_CACHEOP_WAR_IMPL					\
 do {									\
-	if (R4600_V2_HIT_CACHEOP_WAR &&					\
-	    (read_c0_prid() & 0xfff0) == 0x2020) {	/* R4600 V2.0 */\
+	if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())		\
 		*(volatile unsigned long *)KSEG1;			\
-	}								\
 	if (R4600_V1_HIT_CACHEOP_WAR)					\
 		__asm__ __volatile__("nop;nop;nop;nop");		\
 } while (0)
@@ -104,6 +105,15 @@ static inline void r4k_blast_dcache_setu
 #define CACHE32_UNROLL32_ALIGN	JUMP_TO_ALIGN(10) /* 32 * 32 = 1024 */
 #define CACHE32_UNROLL32_ALIGN2	JUMP_TO_ALIGN(11)
 
+static inline void blast_r4600_v1_icache32(void)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	blast_icache32();
+	local_irq_restore(flags);
+}
+
 static inline void tx49_blast_icache32(void)
 {
 	unsigned long start = KSEG0;
@@ -125,6 +135,15 @@ static inline void tx49_blast_icache32(v
 			cache32_unroll32(addr|ws,Index_Invalidate_I);
 }
 
+static inline void blast_icache32_r4600_v1_page_indexed(unsigned long page)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	blast_icache32_page_indexed(page);
+	local_irq_restore(flags);
+}
+
 static inline void tx49_blast_icache32_page_indexed(unsigned long page)
 {
 	unsigned long start = page;
@@ -168,11 +187,17 @@ static inline void r4k_blast_icache_page
 
 	if (ic_lsize == 16)
 		r4k_blast_icache_page_indexed = blast_icache16_page_indexed;
-	else if (ic_lsize == 32 && TX49XX_ICACHE_INDEX_INV_WAR)
-		r4k_blast_icache_page_indexed = tx49_blast_icache32_page_indexed;
-	else if (ic_lsize == 32)
-		r4k_blast_icache_page_indexed = blast_icache32_page_indexed;
-	else if (ic_lsize == 64)
+	else if (ic_lsize == 32) {
+		if (TX49XX_ICACHE_INDEX_INV_WAR)
+			r4k_blast_icache_page_indexed =
+				tx49_blast_icache32_page_indexed;
+		else if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x())
+			r4k_blast_icache_page_indexed =
+				blast_icache32_r4600_v1_page_indexed;
+		else
+			r4k_blast_icache_page_indexed =
+				blast_icache32_page_indexed;
+	} else if (ic_lsize == 64)
 		r4k_blast_icache_page_indexed = blast_icache64_page_indexed;
 }
 
@@ -184,11 +209,14 @@ static inline void r4k_blast_icache_setu
 
 	if (ic_lsize == 16)
 		r4k_blast_icache = blast_icache16;
-	else if (ic_lsize == 32 && TX49XX_ICACHE_INDEX_INV_WAR)
-		r4k_blast_icache = tx49_blast_icache32;
-	else if (ic_lsize == 32)
-		r4k_blast_icache = blast_icache32;
-	else if (ic_lsize == 64)
+	else if (ic_lsize == 32) {
+		if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x())
+			r4k_blast_icache = blast_r4600_v1_icache32;
+		else if (TX49XX_ICACHE_INDEX_INV_WAR)
+			r4k_blast_icache = tx49_blast_icache32;
+		else if (ic_lsize == 32)
+			r4k_blast_icache = blast_icache32;
+	} else if (ic_lsize == 64)
 		r4k_blast_icache = blast_icache64;
 }
 
@@ -352,6 +380,7 @@ static void r4k_flush_data_cache_page(un
 static void r4k_flush_icache_range(unsigned long start, unsigned long end)
 {
 	unsigned long dc_lsize = current_cpu_data.dcache.linesz;
+	unsigned long ic_lsize = current_cpu_data.icache.linesz;
 	unsigned long addr, aend;
 
 	if (!cpu_has_ic_fills_f_dc) {
@@ -374,14 +403,14 @@ static void r4k_flush_icache_range(unsig
 	if (end - start > icache_size)
 		r4k_blast_icache();
 	else {
-		addr = start & ~(dc_lsize - 1);
-		aend = (end - 1) & ~(dc_lsize - 1);
+		addr = start & ~(ic_lsize - 1);
+		aend = (end - 1) & ~(ic_lsize - 1);
 		while (1) {
 			/* Hit_Invalidate_I */
 			protected_flush_icache_line(addr);
 			if (addr == aend)
 				break;
-			addr += dc_lsize;
+			addr += ic_lsize;
 		}
 	}
 }
@@ -445,6 +474,9 @@ static void r4k_dma_cache_wback_inv(unsi
 {
 	unsigned long end, a;
 
+	/* Catch bad driver code */
+	BUG_ON(size == 0);
+
 	if (cpu_has_subset_pcaches) {
 		unsigned long sc_lsize = current_cpu_data.scache.linesz;
 
@@ -492,6 +524,9 @@ static void r4k_dma_cache_inv(unsigned l
 {
 	unsigned long end, a;
 
+	/* Catch bad driver code */
+	BUG_ON(size == 0);
+
 	if (cpu_has_subset_pcaches) {
 		unsigned long sc_lsize = current_cpu_data.scache.linesz;
 
@@ -754,7 +789,10 @@ static void __init probe_pcache(void)
 		c->dcache.ways = 4;
 		c->dcache.waybit = ffs(dcache_size / c->dcache.ways) - 1;
 
-		c->options |= MIPS_CPU_CACHE_CDEX_P | MIPS_CPU_PREFETCH;
+#if !defined(CONFIG_SMP) || !defined(RM9000_CDEX_SMP_WAR)
+		c->options |= MIPS_CPU_CACHE_CDEX_P;
+#endif
+		c->options |= MIPS_CPU_PREFETCH;
 		break;
 
 	default:
@@ -852,7 +890,7 @@ static void __init probe_pcache(void)
 	       cpu_has_vtag_icache ? "virtually tagged" : "physically tagged",
 	       way_string[c->icache.ways], c->icache.linesz);
 
-	printk("Primary data cache %ldkB %s, linesize %d bytes.\n",
+	printk("Primary data cache %ldkB, %s, linesize %d bytes.\n",
 	       dcache_size >> 10, way_string[c->dcache.ways], c->dcache.linesz);
 }
 
@@ -937,10 +975,8 @@ static void __init setup_scache(void)
 	 * Linux memory managment.
 	 */
 	switch (c->cputype) {
-	case CPU_R4000PC:
 	case CPU_R4000SC:
 	case CPU_R4000MC:
-	case CPU_R4400PC:
 	case CPU_R4400SC:
 	case CPU_R4400MC:
 		probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache));
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/mm/c-sb1.c linux-2.4.29-pre3/arch/mips/mm/c-sb1.c
--- linux-2.4.28/arch/mips/mm/c-sb1.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/mm/c-sb1.c	2004-12-22 16:07:09.887673400 +0000
@@ -2,6 +2,7 @@
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org)
  * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation
+ * Copyright (C) 2004  Maciej W. Rozycki
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -31,17 +32,17 @@ extern void sb1_dma_init(void);
 static unsigned long icache_size;
 static unsigned long dcache_size;
 
-static unsigned long icache_line_size;
-static unsigned long dcache_line_size;
+static unsigned short icache_line_size;
+static unsigned short dcache_line_size;
 
 static unsigned int icache_index_mask;
 static unsigned int dcache_index_mask;
 
-static unsigned long icache_assoc;
-static unsigned long dcache_assoc;
+static unsigned short icache_assoc;
+static unsigned short dcache_assoc;
 
-static unsigned int icache_sets;
-static unsigned int dcache_sets;
+static unsigned short icache_sets;
+static unsigned short dcache_sets;
 
 static unsigned int icache_range_cutoff;
 static unsigned int dcache_range_cutoff;
@@ -231,8 +232,8 @@ static void sb1_flush_cache_page(struct 
 	local_sb1_flush_cache_page(vma, addr);
 }
 #else
-void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr);
-asm("sb1_flush_cache_page = local_sb1_flush_cache_page");
+void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr)
+	__attribute__((alias("local_sb1_flush_cache_page")));
 #endif
 
 /*
@@ -280,8 +281,8 @@ static void local_sb1___flush_cache_all(
 }
 
 #ifdef CONFIG_SMP
-extern void sb1___flush_cache_all_ipi(void *ignored);
-asm("sb1___flush_cache_all_ipi = local_sb1___flush_cache_all");
+void sb1___flush_cache_all_ipi(void *ignored)
+	__attribute__((alias("local_sb1___flush_cache_all")));
 
 static void sb1___flush_cache_all(void)
 {
@@ -289,8 +290,8 @@ static void sb1___flush_cache_all(void)
 	local_sb1___flush_cache_all();
 }
 #else
-extern void sb1___flush_cache_all(void);
-asm("sb1___flush_cache_all = local_sb1___flush_cache_all");
+void sb1___flush_cache_all(void)
+	__attribute__((alias("local_sb1___flush_cache_all")));
 #endif
 
 /*
@@ -340,8 +341,8 @@ void sb1_flush_icache_range(unsigned lon
 	local_sb1_flush_icache_range(start, end);
 }
 #else
-void sb1_flush_icache_range(unsigned long start, unsigned long end);
-asm("sb1_flush_icache_range = local_sb1_flush_icache_range");
+void sb1_flush_icache_range(unsigned long start, unsigned long end)
+	__attribute__((alias("local_sb1_flush_icache_range")));
 #endif
 
 /*
@@ -398,8 +399,8 @@ static void sb1_flush_icache_page(struct
 	local_sb1_flush_icache_page(vma, page);
 }
 #else
-void sb1_flush_icache_page(struct vm_area_struct *vma, struct page *page);
-asm("sb1_flush_icache_page = local_sb1_flush_icache_page");
+void sb1_flush_icache_page(struct vm_area_struct *vma, struct page *page)
+	__attribute__((alias("local_sb1_flush_icache_page")));
 #endif
 
 /*
@@ -447,8 +448,8 @@ static void sb1_flush_cache_sigtramp(uns
 	smp_call_function(sb1_flush_cache_sigtramp_ipi, (void *) addr, 1, 1);
 }
 #else
-void sb1_flush_cache_sigtramp(unsigned long addr);
-asm("sb1_flush_cache_sigtramp = local_sb1_flush_cache_sigtramp");
+void sb1_flush_cache_sigtramp(unsigned long addr)
+	__attribute__((alias("local_sb1_flush_cache_sigtramp")));
 #endif
 
 
@@ -516,6 +517,11 @@ static unsigned int decode_cache_line_si
  * 9:7   Dcache Associativity
  */
 
+static char *way_string[] = {
+	"direct mapped", "2-way", "3-way", "4-way",
+	"5-way", "6-way", "7-way", "8-way",
+};
+
 static __init void probe_cache_sizes(void)
 {
 	u32 config1;
@@ -540,6 +546,13 @@ static __init void probe_cache_sizes(voi
 	 */
 	icache_range_cutoff = icache_sets * icache_line_size;
 	dcache_range_cutoff = (dcache_sets / 2) * icache_line_size;
+
+	printk("Primary instruction cache %ldkB, %s, linesize %d bytes.\n",
+	       icache_size >> 10, way_string[icache_assoc - 1],
+	       icache_line_size);
+	printk("Primary data cache %ldkB, %s, linesize %d bytes.\n",
+	       dcache_size >> 10, way_string[dcache_assoc - 1],
+	       dcache_line_size);
 }
 
 /*
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/mm/c-tx39.c linux-2.4.29-pre3/arch/mips/mm/c-tx39.c
--- linux-2.4.28/arch/mips/mm/c-tx39.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/mm/c-tx39.c	2004-12-22 16:05:31.046699512 +0000
@@ -69,6 +69,9 @@ static void tx39h_dma_cache_wback_inv(un
 	unsigned long end, a;
 	unsigned long dc_lsize = current_cpu_data.dcache.linesz;
 
+	/* Catch bad driver code */
+	BUG_ON(size == 0);
+
 	iob();
 	a = addr & ~(dc_lsize - 1);
 	end = (addr + size - 1) & ~(dc_lsize - 1);
@@ -480,9 +483,9 @@ void __init ld_mmu_tx39(void)
 	current_cpu_data.icache.waybit = 0;
 	current_cpu_data.dcache.waybit = 0;
 
-	printk("Primary instruction cache %ldkb, linesize %d bytes\n",
+	printk("Primary instruction cache %ldkB, linesize %d bytes\n",
 		icache_size >> 10, current_cpu_data.icache.linesz);
-	printk("Primary data cache %ldkb, linesize %d bytes\n",
+	printk("Primary data cache %ldkB, linesize %d bytes\n",
 		dcache_size >> 10, current_cpu_data.dcache.linesz);
 
 	build_clear_page();
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/mm/ioremap.c linux-2.4.29-pre3/arch/mips/mm/ioremap.c
--- linux-2.4.28/arch/mips/mm/ioremap.c	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/mm/ioremap.c	2004-12-22 16:06:42.072901888 +0000
@@ -162,7 +162,7 @@ void * __ioremap(phys_t phys_addr, phys_
 	 */
 	offset = phys_addr & ~PAGE_MASK;
 	phys_addr &= PAGE_MASK;
-	size = PAGE_ALIGN(last_addr) - phys_addr;
+	size = PAGE_ALIGN(last_addr + 1) - phys_addr;
 
 	/*
 	 * Ok, go for it..
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/mm/pg-r4k.c linux-2.4.29-pre3/arch/mips/mm/pg-r4k.c
--- linux-2.4.28/arch/mips/mm/pg-r4k.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/mm/pg-r4k.c	2004-12-22 16:06:45.465386152 +0000
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2003 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org)
  */
 #include <linux/config.h>
 #include <linux/init.h>
@@ -11,6 +11,7 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/module.h>
+#include <linux/proc_fs.h>
 
 #include <asm/cacheops.h>
 #include <asm/inst.h>
@@ -25,28 +26,30 @@
 #include <asm/cpu.h>
 #include <asm/war.h>
 
+#define half_scache_line_size()		(cpu_scache_line_size() >> 1)
+
 /*
  * Maximum sizes:
  *
- * R4000 16 bytes D-cache, 128 bytes S-cache:		0x78 bytes
- * R4600 v1.7:						0x5c bytes
- * R4600 v2.0:						0x60 bytes
- * With prefetching, 16 byte strides			0xa0 bytes
+ * R4000 128 bytes S-cache:		0x58 bytes
+ * R4600 v1.7:				0x5c bytes
+ * R4600 v2.0:				0x60 bytes
+ * With prefetching, 16 byte strides	0xa0 bytes
  */
 
-static unsigned int clear_page_array[0xa0 / 4];
+static unsigned int clear_page_array[0x130 / 4];
 
 void clear_page(void * page) __attribute__((alias("clear_page_array")));
 
 /*
  * Maximum sizes:
  *
- * R4000 16 bytes D-cache, 128 bytes S-cache:		0xbc bytes
- * R4600 v1.7:						0x80 bytes
- * R4600 v2.0:						0x84 bytes
- * With prefetching, 16 byte strides			0xb8 bytes
+ * R4000 128 bytes S-cache:		0x11c bytes
+ * R4600 v1.7:				0x080 bytes
+ * R4600 v2.0:				0x07c bytes
+ * With prefetching, 16 byte strides	0x0b8 bytes
  */
-static unsigned int copy_page_array[0xb8 / 4];
+static unsigned int copy_page_array[0x148 / 4];
 
 void copy_page(void *to, void *from) __attribute__((alias("copy_page_array")));
 
@@ -67,12 +70,58 @@ static int pref_offset_copy  __initdata 
 static unsigned int pref_src_mode __initdata;
 static unsigned int pref_dst_mode __initdata;
 
-static int has_scache __initdata = 0;
-static int load_offset __initdata = 0;
-static int store_offset __initdata = 0;
+static int load_offset __initdata;
+static int store_offset __initdata;
 
 static unsigned int __initdata *dest, *epc;
 
+static unsigned int instruction_pending;
+static union mips_instruction delayed_mi;
+
+static void __init emit_instruction(union mips_instruction mi)
+{
+	if (instruction_pending)
+		*epc++ = delayed_mi.word;
+
+	instruction_pending = 1;
+	delayed_mi = mi;
+}
+
+static inline void flush_delay_slot_or_nop(void)
+{
+	if (instruction_pending) {
+		*epc++ = delayed_mi.word;
+		instruction_pending = 0;
+		return;
+	}
+
+	*epc++ = 0;
+}
+
+static inline unsigned int *label(void)
+{
+	if (instruction_pending) {
+		*epc++ = delayed_mi.word;
+		instruction_pending = 0;
+	}
+
+	return epc;
+}
+
+static inline void build_insn_word(unsigned int word)
+{
+	union mips_instruction mi;
+
+	mi.word		 = word;
+
+	emit_instruction(mi);
+}
+
+static inline void build_nop(void)
+{
+	build_insn_word(0);			/* nop */
+}
+
 static inline void build_src_pref(int advance)
 {
 	if (!(load_offset & (cpu_dcache_line_size() - 1))) {
@@ -83,25 +132,28 @@ static inline void build_src_pref(int ad
 		mi.i_format.rt         = pref_src_mode;
 		mi.i_format.simmediate = load_offset + advance;
 
-		*epc++ = mi.word;
+		emit_instruction(mi);
 	}
 }
 
 static inline void __build_load_reg(int reg)
 {
 	union mips_instruction mi;
+	unsigned int width;
 
-	if (cpu_has_64bit_registers)
+	if (cpu_has_64bit_registers) {
 		mi.i_format.opcode     = ld_op;
-	else
+		width = 8;
+	} else {
 		mi.i_format.opcode     = lw_op;
+		width = 4;
+	}
 	mi.i_format.rs         = 5;		/* $a1 */
-	mi.i_format.rt         = reg;		/* $zero */
+	mi.i_format.rt         = reg;		/* $reg */
 	mi.i_format.simmediate = load_offset;
 
-	load_offset += (cpu_has_64bit_registers ? 8 : 4);
-
-	*epc++ = mi.word;
+	load_offset += width;
+	emit_instruction(mi);
 }
 
 static inline void build_load_reg(int reg)
@@ -122,87 +174,71 @@ static inline void build_dst_pref(int ad
 		mi.i_format.rt         = pref_dst_mode;
 		mi.i_format.simmediate = store_offset + advance;
 
-		*epc++ = mi.word;
+		emit_instruction(mi);
 	}
 }
 
-static inline void build_cdex(void)
+static inline void build_cdex_s(void)
 {
 	union mips_instruction mi;
 
-	if (cpu_has_cache_cdex_s &&
-	    !(store_offset & (cpu_scache_line_size() - 1))) {
+	if ((store_offset & (cpu_scache_line_size() - 1)))
+		return;
 
-		mi.c_format.opcode     = cache_op;
-		mi.c_format.rs         = 4;	/* $a0 */
-		mi.c_format.c_op       = 3;	/* Create Dirty Exclusive */
-		mi.c_format.cache      = 3;	/* Secondary Data Cache */
-		mi.c_format.simmediate = store_offset;
+	mi.c_format.opcode     = cache_op;
+	mi.c_format.rs         = 4;		/* $a0 */
+	mi.c_format.c_op       = 3;		/* Create Dirty Exclusive */
+	mi.c_format.cache      = 3;		/* Secondary Data Cache */
+	mi.c_format.simmediate = store_offset;
 
-		*epc++ = mi.word;
-	}
+	emit_instruction(mi);
+}
+
+static inline void build_cdex_p(void)
+{
+	union mips_instruction mi;
 
 	if (store_offset & (cpu_dcache_line_size() - 1))
 		return;
 
 	if (R4600_V1_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2010)) {
-		*epc++ = 0;			/* nop */
-		*epc++ = 0;			/* nop */
-		*epc++ = 0;			/* nop */
-		*epc++ = 0;			/* nop */
+		build_nop();
+		build_nop();
+		build_nop();
+		build_nop();
 	}
 
+	if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020))
+		build_insn_word(0x8c200000);	/* lw      $zero, ($at) */
+
 	mi.c_format.opcode     = cache_op;
 	mi.c_format.rs         = 4;		/* $a0 */
 	mi.c_format.c_op       = 3;		/* Create Dirty Exclusive */
 	mi.c_format.cache      = 1;		/* Data Cache */
 	mi.c_format.simmediate = store_offset;
 
-	*epc++ = mi.word;
+	emit_instruction(mi);
 }
 
-static inline void __build_store_zero_reg(void)
+static void __build_store_reg(int reg)
 {
 	union mips_instruction mi;
+	unsigned int width;
 
-	if (cpu_has_64bits)
+	if (cpu_has_64bit_gp_regs ||
+	    (cpu_has_64bit_zero_reg && reg == 0)) {
 		mi.i_format.opcode     = sd_op;
-	else
-		mi.i_format.opcode     = sw_op;
-	mi.i_format.rs         = 4;		/* $a0 */
-	mi.i_format.rt         = 0;		/* $zero */
-	mi.i_format.simmediate = store_offset;
-
-	store_offset += (cpu_has_64bits ? 8 : 4);
-
-	*epc++ = mi.word;
-}
-
-static inline void __build_store_reg(int reg)
-{
-	union mips_instruction mi;
-	int reg_size;
-
-#ifdef CONFIG_MIPS32
-	if (cpu_has_64bit_registers && reg == 0) {
-		mi.i_format.opcode     = sd_op;
-		reg_size               = 8;
+		width = 8;
 	} else {
 		mi.i_format.opcode     = sw_op;
-		reg_size               = 4;
+		width = 4;
 	}
-#endif
-#ifdef CONFIG_MIPS64
-	mi.i_format.opcode     = sd_op;
-	reg_size               = 8;
-#endif
 	mi.i_format.rs         = 4;		/* $a0 */
-	mi.i_format.rt         = reg;		/* $zero */
+	mi.i_format.rt         = reg;		/* $reg */
 	mi.i_format.simmediate = store_offset;
 
-	store_offset += reg_size;
-
-	*epc++ = mi.word;
+	store_offset += width;
+	emit_instruction(mi);
 }
 
 static inline void build_store_reg(int reg)
@@ -212,13 +248,15 @@ static inline void build_store_reg(int r
 			build_dst_pref(pref_offset_copy);
 		else
 			build_dst_pref(pref_offset_clear);
+	else if (cpu_has_cache_cdex_s)
+		build_cdex_s();
 	else if (cpu_has_cache_cdex_p)
-		build_cdex();
+		build_cdex_p();
 
 	__build_store_reg(reg);
 }
 
-static inline void build_addiu_at_a0(unsigned long offset)
+static inline void build_addiu_a2_a0(unsigned long offset)
 {
 	union mips_instruction mi;
 
@@ -226,10 +264,10 @@ static inline void build_addiu_at_a0(uns
 
 	mi.i_format.opcode     = cpu_has_64bit_addresses ? daddiu_op : addiu_op;
 	mi.i_format.rs         = 4;		/* $a0 */
-	mi.i_format.rt         = 1;		/* $at */
+	mi.i_format.rt         = 6;		/* $a2 */
 	mi.i_format.simmediate = offset;
 
-	*epc++ = mi.word;
+	emit_instruction(mi);
 }
 
 static inline void build_addiu_a1(unsigned long offset)
@@ -245,7 +283,7 @@ static inline void build_addiu_a1(unsign
 
 	load_offset -= offset;
 
-	*epc++ = mi.word;
+	emit_instruction(mi);
 }
 
 static inline void build_addiu_a0(unsigned long offset)
@@ -261,7 +299,7 @@ static inline void build_addiu_a0(unsign
 
 	store_offset -= offset;
 
-	*epc++ = mi.word;
+	emit_instruction(mi);
 }
 
 static inline void build_bne(unsigned int *dest)
@@ -269,16 +307,12 @@ static inline void build_bne(unsigned in
 	union mips_instruction mi;
 
 	mi.i_format.opcode = bne_op;
-	mi.i_format.rs     = 1;			/* $at */
+	mi.i_format.rs     = 6;			/* $a2 */
 	mi.i_format.rt     = 4;			/* $a0 */
 	mi.i_format.simmediate = dest - epc - 1;
 
 	*epc++ = mi.word;
-}
-
-static inline void build_nop(void)
-{
-	*epc++ = 0;
+	flush_delay_slot_or_nop();
 }
 
 static inline void build_jr_ra(void)
@@ -293,19 +327,34 @@ static inline void build_jr_ra(void)
 	mi.r_format.func   = jr_op;
 
 	*epc++ = mi.word;
+	flush_delay_slot_or_nop();
 }
 
 void __init build_clear_page(void)
 {
+	unsigned int loop_start;
+
 	epc = (unsigned int *) &clear_page_array;
+	instruction_pending = 0;
+	store_offset = 0;
 
 	if (cpu_has_prefetch) {
 		switch (current_cpu_data.cputype) {
+		case CPU_RM9000:
+			/*
+			 * As a workaround for erratum G105 which make the
+			 * PrepareForStore hint unusable we fall back to
+			 * StoreRetained on the RM9000.  Once it is known which
+			 * versions of the RM9000 we'll be able to condition-
+			 * alize this.
+			 */
+
 		case CPU_R10000:
 		case CPU_R12000:
 			pref_src_mode = Pref_LoadStreamed;
 			pref_dst_mode = Pref_StoreRetained;
 			break;
+
 		default:
 			pref_src_mode = Pref_LoadStreamed;
 			pref_dst_mode = Pref_PrepareForStore;
@@ -313,64 +362,50 @@ void __init build_clear_page(void)
 		}
 	}
 
-	build_addiu_at_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0));
+	build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0));
 
-	if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020)) {
-		*epc++ = 0x40026000;		/* mfc0    $v0, $12	*/
-		*epc++ = 0x34410001;		/* ori     $at, v0, 0x1	*/
-		*epc++ = 0x38210001;		/* xori    $at, at, 0x1	*/
-		*epc++ = 0x40816000;		/* mtc0    $at, $12	*/
-		*epc++ = 0x00000000;		/* nop			*/
-		*epc++ = 0x00000000;		/* nop			*/
-		*epc++ = 0x00000000;		/* nop			*/
-		*epc++ = 0x3c01a000;		/* lui     $at, 0xa000  */
-		*epc++ = 0x8c200000;		/* lw      $zero, ($at) */
-	}
+	if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020))
+		build_insn_word(0x3c01a000);	/* lui     $at, 0xa000  */
 
-dest = epc;
-	build_store_reg(0);
-	build_store_reg(0);
-	build_store_reg(0);
-	build_store_reg(0);
-	if (has_scache && cpu_scache_line_size() == 128) {
+dest = label();
+	do {
 		build_store_reg(0);
 		build_store_reg(0);
 		build_store_reg(0);
 		build_store_reg(0);
-	}
+	} while (store_offset < half_scache_line_size());
 	build_addiu_a0(2 * store_offset);
-	build_store_reg(0);
-	build_store_reg(0);
-	if (has_scache && cpu_scache_line_size() == 128) {
+	loop_start = store_offset;
+	do {
 		build_store_reg(0);
 		build_store_reg(0);
 		build_store_reg(0);
 		build_store_reg(0);
-	}
-	build_store_reg(0);
+	} while ((store_offset - loop_start) < half_scache_line_size());
 	build_bne(dest);
-	 build_store_reg(0);
 
 	if (cpu_has_prefetch && pref_offset_clear) {
-		build_addiu_at_a0(pref_offset_clear);
-	dest = epc;
-		__build_store_reg(0);
-		__build_store_reg(0);
-		__build_store_reg(0);
-		__build_store_reg(0);
+		build_addiu_a2_a0(pref_offset_clear);
+	dest = label();
+		loop_start = store_offset;
+		do {
+			__build_store_reg(0);
+			__build_store_reg(0);
+			__build_store_reg(0);
+			__build_store_reg(0);
+		} while ((store_offset - loop_start) < half_scache_line_size());
 		build_addiu_a0(2 * store_offset);
-		__build_store_reg(0);
-		__build_store_reg(0);
-		__build_store_reg(0);
+		loop_start = store_offset;
+		do {
+			__build_store_reg(0);
+			__build_store_reg(0);
+			__build_store_reg(0);
+			__build_store_reg(0);
+		} while ((store_offset - loop_start) < half_scache_line_size());
 		build_bne(dest);
-		 __build_store_reg(0);
 	}
 
 	build_jr_ra();
-	if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020))
-		*epc++ = 0x40826000;		/* mtc0    $v0, $12	*/
-	else
-		build_nop();
 
 	flush_icache_range((unsigned long)&clear_page_array,
 	                   (unsigned long) epc);
@@ -380,32 +415,20 @@ dest = epc;
 
 void __init build_copy_page(void)
 {
+	unsigned int loop_start;
+
 	epc = (unsigned int *) &copy_page_array;
+	store_offset = load_offset = 0;
+	instruction_pending = 0;
 
-	build_addiu_at_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0));
+	build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0));
 
-	if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020)) {
-		*epc++ = 0x40026000;		/* mfc0    $v0, $12	*/
-		*epc++ = 0x34410001;		/* ori     $at, v0, 0x1	*/
-		*epc++ = 0x38210001;		/* xori    $at, at, 0x1	*/
-		*epc++ = 0x40816000;		/* mtc0    $at, $12	*/
-		*epc++ = 0x00000000;		/* nop			*/
-		*epc++ = 0x00000000;		/* nop			*/
-		*epc++ = 0x00000000;		/* nop			*/
-		*epc++ = 0x3c01a000;		/* lui     $at, 0xa000  */
-		*epc++ = 0x8c200000;		/* lw      $zero, ($at) */
-	}
+	if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020))
+		build_insn_word(0x3c01a000);	/* lui     $at, 0xa000  */
 
-dest = epc;
-	build_load_reg( 8);
-	build_load_reg( 9);
-	build_load_reg(10);
-	build_load_reg(11);
-	build_store_reg( 8);
-	build_store_reg( 9);
-	build_store_reg(10);
-	build_store_reg(11);
-	if (has_scache && cpu_scache_line_size() == 128) {
+dest = label();
+	loop_start = store_offset;
+	do {
 		build_load_reg( 8);
 		build_load_reg( 9);
 		build_load_reg(10);
@@ -414,18 +437,11 @@ dest = epc;
 		build_store_reg( 9);
 		build_store_reg(10);
 		build_store_reg(11);
-	}
+	} while ((store_offset - loop_start) < half_scache_line_size());
 	build_addiu_a0(2 * store_offset);
 	build_addiu_a1(2 * load_offset);
-	build_load_reg( 8);
-	build_load_reg( 9);
-	build_load_reg(10);
-	build_load_reg(11);
-	build_store_reg( 8);
-	build_store_reg( 9);
-	build_store_reg(10);
-	if (has_scache && cpu_scache_line_size() == 128) {
-		build_store_reg(11);
+	loop_start = store_offset;
+	do {
 		build_load_reg( 8);
 		build_load_reg( 9);
 		build_load_reg(10);
@@ -433,39 +449,44 @@ dest = epc;
 		build_store_reg( 8);
 		build_store_reg( 9);
 		build_store_reg(10);
-	}
+		build_store_reg(11);
+	} while ((store_offset - loop_start) < half_scache_line_size());
 	build_bne(dest);
-	 build_store_reg(11);
 
 	if (cpu_has_prefetch && pref_offset_copy) {
-		build_addiu_at_a0(pref_offset_copy);
-	dest = epc;
-		__build_load_reg( 8);
-		__build_load_reg( 9);
-		__build_load_reg(10);
-		__build_load_reg(11);
-		__build_store_reg( 8);
-		__build_store_reg( 9);
-		__build_store_reg(10);
-		__build_store_reg(11);
+		build_addiu_a2_a0(pref_offset_copy);
+	dest = label();
+		loop_start = store_offset;
+		do {
+			__build_load_reg( 8);
+			__build_load_reg( 9);
+			__build_load_reg(10);
+			__build_load_reg(11);
+			__build_store_reg( 8);
+			__build_store_reg( 9);
+			__build_store_reg(10);
+			__build_store_reg(11);
+		} while ((store_offset - loop_start) < half_scache_line_size());
 		build_addiu_a0(2 * store_offset);
 		build_addiu_a1(2 * load_offset);
-		__build_load_reg( 8);
-		__build_load_reg( 9);
-		__build_load_reg(10);
-		__build_load_reg(11);
-		__build_store_reg( 8);
-		__build_store_reg( 9);
-		__build_store_reg(10);
+		loop_start = store_offset;
+		do {
+			__build_load_reg( 8);
+			__build_load_reg( 9);
+			__build_load_reg(10);
+			__build_load_reg(11);
+			__build_store_reg( 8);
+			__build_store_reg( 9);
+			__build_store_reg(10);
+			__build_store_reg(11);
+		} while ((store_offset - loop_start) < half_scache_line_size());
 		build_bne(dest);
-		 __build_store_reg(11);
 	}
 
 	build_jr_ra();
-	if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020))
-		*epc++ = 0x40826000;		/* mtc0    $v0, $12	*/
-	else
-		build_nop();
+
+	flush_icache_range((unsigned long)&copy_page_array,
+	                   (unsigned long) epc);
 
 	BUG_ON(epc > copy_page_array + ARRAY_SIZE(copy_page_array));
 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/mm/sc-ip22.c linux-2.4.29-pre3/arch/mips/mm/sc-ip22.c
--- linux-2.4.28/arch/mips/mm/sc-ip22.c	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/mm/sc-ip22.c	2004-12-22 16:05:47.969126912 +0000
@@ -65,8 +65,8 @@ static void indy_sc_wback_invalidate(uns
 	printk("indy_sc_wback_invalidate[%08lx,%08lx]", addr, size);
 #endif
 
-	if (!size)
-		return;
+	/* Catch bad driver code */
+	BUG_ON(size == 0);
 
 	/* Which lines to flush?  */
 	first_line = SC_INDEX(addr);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/mm/sc-r5k.c linux-2.4.29-pre3/arch/mips/mm/sc-r5k.c
--- linux-2.4.28/arch/mips/mm/sc-r5k.c	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/mm/sc-r5k.c	2004-12-22 16:07:37.457482152 +0000
@@ -47,6 +47,9 @@ static void r5k_dma_cache_inv_sc(unsigne
 {
 	unsigned long end, a;
 
+	/* Catch bad driver code */
+	BUG_ON(size == 0);
+
 	if (size >= scache_size) {
 		blast_r5000_scache();
 		return;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/mm/sc-rm7k.c linux-2.4.29-pre3/arch/mips/mm/sc-rm7k.c
--- linux-2.4.28/arch/mips/mm/sc-rm7k.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/mm/sc-rm7k.c	2004-12-22 16:07:01.366968744 +0000
@@ -1,8 +1,11 @@
 /*
  * sc-rm7k.c: RM7000 cache management functions.
  *
- * Copyright (C) 1997, 2001, 2003 Ralf Baechle (ralf@gnu.org),
+ * Copyright (C) 1997, 2001, 2003, 2004 Ralf Baechle (ralf@linux-mips.org)
  */
+
+#undef DEBUG
+
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
@@ -17,8 +20,6 @@
 #define sc_lsize	32
 #define tc_pagesize	(32*128)
 
-static unsigned long scache_way_size = 32;		/* HACKKKKK!!! */
-
 /* Secondary cache parameters. */
 #define scache_size	(256*1024)	/* Fixed to 256KiB on RM7000 */
 
@@ -36,9 +37,10 @@ static void rm7k_sc_wback_inv(unsigned l
 {
 	unsigned long end, a;
 
-#ifdef DEBUG_CACHE
-	printk("rm7k_sc_wback_inv[%08lx,%08lx]", addr, size);
-#endif
+	pr_debug("rm7k_sc_wback_inv[%08lx,%08lx]", addr, size);
+
+	/* Catch bad driver code */
+	BUG_ON(size == 0);
 
 	a = addr & ~(sc_lsize - 1);
 	end = (addr + size - 1) & ~(sc_lsize - 1);
@@ -66,9 +68,10 @@ static void rm7k_sc_inv(unsigned long ad
 {
 	unsigned long end, a;
 
-#ifdef DEBUG_CACHE
-	printk("rm7k_sc_inv[%08lx,%08lx]", addr, size);
-#endif
+	pr_debug("rm7k_sc_inv[%08lx,%08lx]", addr, size);
+
+	/* Catch bad driver code */
+	BUG_ON(size == 0);
 
 	a = addr & ~(sc_lsize - 1);
 	end = (addr + size - 1) & ~(sc_lsize - 1);
@@ -107,16 +110,16 @@ static void rm7k_sc_inv(unsigned long ad
  *
  * It seems we get our kicks from relying on unguaranteed behaviour in GCC
  */
-static __init void rm7k_sc_enable(void)
+static __init void __rm7k_sc_enable(void)
 {
 	int i;
 
-	set_c0_config(1<<3);				/* CONF_SE */
+	set_c0_config(1 << 3);				/* CONF_SE */
 
 	write_c0_taglo(0);
 	write_c0_taghi(0);
 
-	for (i=0; i<scache_size; i+=sc_lsize) {
+	for (i = 0; i < scache_size; i += sc_lsize) {
 		__asm__ __volatile__ (
 		      ".set noreorder\n\t"
 		      ".set mips3\n\t"
@@ -124,11 +127,21 @@ static __init void rm7k_sc_enable(void)
 		      ".set mips0\n\t"
 		      ".set reorder"
 		      :
-		      : "r" (KSEG0ADDR(i)),
-		        "i" (Index_Store_Tag_SD));
+		      : "r" (KSEG0ADDR(i)), "i" (Index_Store_Tag_SD));
 	}
 }
 
+static __init void rm7k_sc_enable(void)
+{
+	void (*func)(void) = (void *) KSEG1ADDR(&__rm7k_sc_enable);
+
+	if (read_c0_config() & 0x08)			/* CONF_SE */
+		return;
+
+	printk(KERN_INFO "Enabling secondary cache...");
+	func();
+}
+
 static void rm7k_sc_disable(void)
 {
 	clear_c0_config(1<<3);				/* CONF_SE */
@@ -136,22 +149,17 @@ static void rm7k_sc_disable(void)
 
 static inline int __init rm7k_sc_probe(void)
 {
-	void (*func)(void) = KSEG1ADDR(&rm7k_sc_enable);
 	unsigned int config = read_c0_config();
 
 	if ((config >> 31) & 1)
 		return 0;
 
-	printk(KERN_INFO "Secondary cache size %ldK, linesize %ld bytes.\n",
+	printk(KERN_INFO "Secondary cache size %dK, linesize %d bytes.\n",
 	       (scache_size >> 10), sc_lsize);
 
 	if ((config >> 3) & 1)                          /* CONF_SE */
 		return 1;
 
-	printk(KERN_INFO "Enabling secondary cache...");
-	func();
-	printk("  done\n");
-
 	/*
 	 * While we're at it let's deal with the tertiary cache.
 	 */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/mm/tlb-r4k.c linux-2.4.29-pre3/arch/mips/mm/tlb-r4k.c
--- linux-2.4.28/arch/mips/mm/tlb-r4k.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/mm/tlb-r4k.c	2004-12-22 16:05:31.878573048 +0000
@@ -21,6 +21,7 @@
 #include <asm/cpu.h>
 #include <asm/bootinfo.h>
 #include <asm/mmu_context.h>
+#include <linux/module.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
 
@@ -46,7 +47,7 @@ void local_flush_tlb_all(void)
 
 	local_irq_save(flags);
 	/* Save old context and create impossible VPN2 value */
-	old_ctx = (read_c0_entryhi() & 0xff);
+	old_ctx = read_c0_entryhi();
 	write_c0_entrylo0(0);
 	write_c0_entrylo1(0);
 	BARRIER;
@@ -100,7 +101,7 @@ void local_flush_tlb_range(struct mm_str
 		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
 		size = (size + 1) >> 1;
 		if (size <= current_cpu_data.tlbsize/2) {
-			int oldpid = read_c0_entryhi() & ASID_MASK;
+			int oldpid = read_c0_entryhi();
 			int newpid = cpu_asid(cpu, mm);
 
 			start &= (PAGE_MASK << 1);
@@ -148,7 +149,7 @@ void local_flush_tlb_page(struct vm_area
 		newpid = cpu_asid(cpu, vma->vm_mm);
 		page &= (PAGE_MASK << 1);
 		local_irq_save(flags);
-		oldpid = (read_c0_entryhi() & 0xff);
+		oldpid = read_c0_entryhi();
 		write_c0_entryhi(page | newpid);
 		BARRIER;
 		tlb_probe();
@@ -180,7 +181,7 @@ void local_flush_tlb_one(unsigned long p
 	int oldpid, idx;
 
 	page &= (PAGE_MASK << 1);
-	oldpid = read_c0_entryhi() & ASID_MASK;
+	oldpid = read_c0_entryhi();
 
 	local_irq_save(flags);
 	write_c0_entryhi(page);
@@ -200,6 +201,8 @@ void local_flush_tlb_one(unsigned long p
 	local_irq_restore(flags);
 }
 
+EXPORT_SYMBOL(local_flush_tlb_one);
+
 /* We will need multiple versions of update_mmu_cache(), one that just
  * updates the TLB with the new pte(s), and another which also checks
  * for the R4k "end of page" hardware bug and does the needy.
@@ -265,6 +268,7 @@ static void r4k_update_mmu_cache_hwbug(s
 				       unsigned long address, pte_t pte)
 {
 	unsigned long flags;
+	unsigned int asid;
 	pgd_t *pgdp;
 	pmd_t *pmdp;
 	pte_t *ptep;
@@ -272,7 +276,8 @@ static void r4k_update_mmu_cache_hwbug(s
 
 	local_irq_save(flags);
 	address &= (PAGE_MASK << 1);
-	write_c0_entryhi(address | (read_c0_entryhi() & 0xff));
+	asid = read_c0_entryhi() & ASID_MASK;
+	write_c0_entryhi(address | asid);
 	pgdp = pgd_offset(vma->vm_mm, address);
 	tlb_probe();
 	pmdp = pmd_offset(pgdp, address);
@@ -300,7 +305,7 @@ void __init add_wired_entry(unsigned lon
 
 	local_irq_save(flags);
 	/* Save old context and create impossible VPN2 value */
-	old_ctx = read_c0_entryhi() & 0xff;
+	old_ctx = read_c0_entryhi();
 	old_pagemask = read_c0_pagemask();
 	wired = read_c0_wired();
 	write_c0_wired(wired + 1);
@@ -340,7 +345,7 @@ __init int add_temporary_entry(unsigned 
 
 	local_irq_save(flags);
 	/* Save old context and create impossible VPN2 value */
-	old_ctx = read_c0_entryhi() & 0xff;
+	old_ctx = read_c0_entryhi();
 	old_pagemask = read_c0_pagemask();
 	wired = read_c0_wired();
 	if (--temp_tlb_entry < wired) {
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/mm/tlb-sb1.c linux-2.4.29-pre3/arch/mips/mm/tlb-sb1.c
--- linux-2.4.28/arch/mips/mm/tlb-sb1.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/mm/tlb-sb1.c	2004-12-22 16:07:04.424503928 +0000
@@ -18,6 +18,7 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 #include <linux/config.h>
+#include <linux/module.h>
 #include <linux/init.h>
 #include <asm/mmu_context.h>
 #include <asm/bootinfo.h>
@@ -118,7 +119,7 @@ void local_flush_tlb_all(void)
  * with the firmware, go back and give all the entries invalid addresses with
  * the normal flush routine.  Wired entries will be killed as well!
  */
-void sb1_sanitize_tlb(void)
+static void __init sb1_sanitize_tlb(void)
 {
 	int entry;
 	long addr = 0;
@@ -238,6 +239,9 @@ void local_flush_tlb_one(unsigned long p
 	local_irq_restore(flags);
 }
 
+/* The highmem code wants this. */
+EXPORT_SYMBOL(local_flush_tlb_one);
+
 /* All entries common to a mm share an asid.  To effectively flush
    these entries, we just bump the asid. */
 void local_flush_tlb_mm(struct mm_struct *mm)
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/momentum/jaguar_atx/Makefile linux-2.4.29-pre3/arch/mips/momentum/jaguar_atx/Makefile
--- linux-2.4.28/arch/mips/momentum/jaguar_atx/Makefile	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/momentum/jaguar_atx/Makefile	2004-12-22 16:07:42.025787664 +0000
@@ -6,10 +6,7 @@
 # unless it's something special (ie not a .c file).
 #
 
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
 
 O_TARGET:= jaguar_atx.o
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/momentum/jaguar_atx/int-handler.S linux-2.4.29-pre3/arch/mips/momentum/jaguar_atx/int-handler.S
--- linux-2.4.28/arch/mips/momentum/jaguar_atx/int-handler.S	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/momentum/jaguar_atx/int-handler.S	2004-12-22 16:05:36.045939512 +0000
@@ -13,7 +13,6 @@
  * Free Software Foundation;  either version 2 of the  License, or (at your
  * option) any later version.
  */
-#define __ASSEMBLY__
 #include <linux/config.h>
 #include <asm/asm.h>
 #include <asm/mipsregs.h>
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/momentum/ocelot_c/int-handler.S linux-2.4.29-pre3/arch/mips/momentum/ocelot_c/int-handler.S
--- linux-2.4.28/arch/mips/momentum/ocelot_c/int-handler.S	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/momentum/ocelot_c/int-handler.S	2004-12-22 16:05:49.429904840 +0000
@@ -12,7 +12,6 @@
  * Free Software Foundation;  either version 2 of the  License, or (at your
  * option) any later version.
  */
-#define __ASSEMBLY__
 #include <linux/config.h>
 #include <asm/asm.h>
 #include <asm/mipsregs.h>
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/momentum/ocelot_g/int-handler.S linux-2.4.29-pre3/arch/mips/momentum/ocelot_g/int-handler.S
--- linux-2.4.28/arch/mips/momentum/ocelot_g/int-handler.S	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/momentum/ocelot_g/int-handler.S	2004-12-22 16:07:51.316375280 +0000
@@ -9,7 +9,6 @@
  * Free Software Foundation;  either version 2 of the  License, or (at your
  * option) any later version.
  */
-#define __ASSEMBLY__
 #include <linux/config.h>
 #include <asm/asm.h>
 #include <asm/mipsregs.h>
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/momentum/ocelot_g/irq.c linux-2.4.29-pre3/arch/mips/momentum/ocelot_g/irq.c
--- linux-2.4.28/arch/mips/momentum/ocelot_g/irq.c	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/momentum/ocelot_g/irq.c	2004-12-22 16:05:33.114385176 +0000
@@ -47,93 +47,6 @@
 #include <asm/mipsregs.h>
 #include <asm/system.h>
 
-
-static spinlock_t rm7000_irq_lock = SPIN_LOCK_UNLOCKED;
-
-/* Function for careful CP0 interrupt mask access */
-static inline void modify_cp0_intmask(unsigned clr_mask_in, unsigned set_mask_in)
-{
-	unsigned long status;
-	unsigned clr_mask;
-	unsigned set_mask;
-
-	/* do the low 8 bits first */
-	clr_mask = 0xff & clr_mask_in;
-	set_mask = 0xff & set_mask_in;
-	status = read_c0_status();
-	status &= ~((clr_mask & 0xFF) << 8);
-	status |= (set_mask & 0xFF) << 8;
-	write_c0_status(status);
-
-	/* do the high 8 bits */
-	clr_mask = 0xff & (clr_mask_in >> 8);
-	set_mask = 0xff & (set_mask_in >> 8);
-	status = read_c0_intcontrol();
-	status &= ~((clr_mask & 0xFF) << 8);
-	status |= (set_mask & 0xFF) << 8;
-	write_c0_intrcontrol(status);
-}
-
-static inline void mask_irq(unsigned int irq)
-{
-	modify_cp0_intmask(irq, 0);
-}
-
-static inline void unmask_irq(unsigned int irq)
-{
-	modify_cp0_intmask(0, irq);
-}
-
-static void enable_cp7000_irq(unsigned int irq)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&rm7000_irq_lock, flags);
-	unmask_irq(1 << irq);
-	spin_unlock_irqrestore(&rm7000_irq_lock, flags);
-}
-
-static unsigned int startup_cp7000_irq(unsigned int irq)
-{
-	enable_cp7000_irq(irq);
-
-	return 0;				/* never anything pending */
-}
-
-static void disable_cp7000_irq(unsigned int irq)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&rm7000_irq_lock, flags);
-	mask_irq(1 << irq);
-	spin_unlock_irqrestore(&rm7000_irq_lock, flags);
-}
-
-#define shutdown_cp7000_irq disable_cp7000_irq
-
-static void mask_and_ack_cp7000_irq(unsigned int irq)
-{
-	mask_irq(1 << irq);
-}
-
-static void end_cp7000_irq(unsigned int irq)
-{
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-		unmask_irq(1 << irq);
-}
-
-static struct hw_interrupt_type cp7000_hpcdma_irq_type = {
-	"CP7000",
-	startup_cp7000_irq,
-	shutdown_cp7000_irq,
-	enable_cp7000_irq,
-	disable_cp7000_irq,
-	mask_and_ack_cp7000_irq,
-	end_cp7000_irq,
-	NULL
-};
-
-
 extern asmlinkage void ocelot_handle_int(void);
 extern void gt64240_irq_init(void);
 
@@ -151,14 +64,8 @@ void __init init_IRQ(void)
 	/* Sets the first-level interrupt dispatcher. */
 	set_except_vector(0, ocelot_handle_int);
 	init_generic_irq();
-
-	for (i = 0; i <= 15; i++) {
-		irq_desc[i].status	= IRQ_DISABLED;
-		irq_desc[i].action	= 0;
-		irq_desc[i].depth	= 1;
-		irq_desc[i].handler	= &cp7000_hpcdma_irq_type;
-	}
-
+	mips_cpu_irq_init(0);
+	rm7k_cpu_irq_init(8);
 	gt64240_irq_init();
 
 #ifdef CONFIG_KGDB
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/pci/Makefile linux-2.4.29-pre3/arch/mips/pci/Makefile
--- linux-2.4.28/arch/mips/pci/Makefile	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/pci/Makefile	2004-12-22 16:07:11.756389312 +0000
@@ -8,8 +8,6 @@
 
 O_TARGET 			:= pci-core.o
 
-export-objs			= pci.o
-
 obj-$(CONFIG_MIPS_BONITO64)	+= ops-bonito64.o
 obj-$(CONFIG_MIPS_GT64120)	+= ops-gt64120.o
 obj-$(CONFIG_MIPS_MSC)		+= ops-msc.o
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/pci/pci.c linux-2.4.29-pre3/arch/mips/pci/pci.c
--- linux-2.4.28/arch/mips/pci/pci.c	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/pci/pci.c	2004-12-22 16:07:14.334997304 +0000
@@ -129,7 +129,7 @@ int pcibios_enable_device(struct pci_dev
 	return pcibios_enable_resources(dev, mask);
 }
 
-#ifdef CONFIG_NEW_PCI
+#ifdef CONFIG_PCI_NEW
 /*
  * Named PCI new and about to die before it's old :-)
  *
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/pmc-sierra/big_sur/Makefile linux-2.4.29-pre3/arch/mips/pmc-sierra/big_sur/Makefile
--- linux-2.4.28/arch/mips/pmc-sierra/big_sur/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/pmc-sierra/big_sur/Makefile	2004-12-22 16:06:05.949393496 +0000
@@ -0,0 +1,11 @@
+#
+# Makefile for the PMC-Sierra Big Sur
+#
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET:= big_sur.o
+
+obj-y  += int-handler.o irq.o big_sur_irq.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/pmc-sierra/big_sur/big_sur_irq.c linux-2.4.29-pre3/arch/mips/pmc-sierra/big_sur/big_sur_irq.c
--- linux-2.4.28/arch/mips/pmc-sierra/big_sur/big_sur_irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/pmc-sierra/big_sur/big_sur_irq.c	2004-12-22 16:06:55.022933184 +0000
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2004 PMC-Sierra Inc.
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * arch/mips/pmc-sierra/big_sur/big_sur_irq.c
+ *     Interrupt routines for Xilinx system controller.  Interrupt numbers 
+ *     are assigned from BIG_SUR_IRQ_BASE to BIG_SUR_IRQ_BASE + 10
+ *
+ * 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/interrupt.h>
+#include <linux/kernel.h>
+#include <asm/ptrace.h>
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include "xilinx_irq.h"
+
+#define	BIG_SUR_IRQ_BASE	16
+
+/* mask off an interrupt -- 1 is enable, 0 is disable */
+static inline void mask_big_sur_irq(unsigned int irq)
+{
+	unsigned long reg_data;
+	
+	reg_data = BIG_SUR_READ(BIG_SUR_INTERRUPT_MASK_1);
+	reg_data &= ~(1 << (irq - BIG_SUR_IRQ_BASE));
+	BIG_SUR_WRITE(BIG_SUR_INTERRUPT_MASK_1, reg_data);
+}
+
+/* unmask an interrupt -- 1 is enable, 0 is disable */
+static inline void unmask_big_sur_irq(unsigned int irq)
+{
+	unsigned long reg_data;
+
+	reg_data = BIG_SUR_READ(BIG_SUR_INTERRUPT_MASK_1);
+	reg_data |= (1 << (irq - BIG_SUR_IRQ_BASE));
+	BIG_SUR_WRITE(BIG_SUR_INTERRUPT_MASK_1, reg_data);
+}
+
+/* Enable IRQ on the Xilinx FPGA */
+static void enable_big_sur_irq(unsigned int irq)
+{
+	unmask_big_sur_irq(irq);
+}
+
+/* Initialize IRQ on the Xilinx FPGA */
+static unsigned int startup_big_sur_irq(unsigned int irq)
+{
+	unmask_big_sur_irq(irq);
+	return 0;
+}
+
+/* Disable the IRQ on the Xilinx FPGA */
+static void disable_big_sur_irq(unsigned int irq)
+{
+	mask_big_sur_irq(irq);
+}
+
+/* Mask and ack an IRQ on the Xilinx FPGA */
+static void mask_and_ack_big_sur_irq(unsigned int irq)
+{
+	mask_big_sur_irq(irq);
+}
+
+/* End IRQ processing on the Xilinx FPGA */
+static void end_big_sur_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+		unmask_big_sur_irq(irq);
+}
+
+/*
+ * Main interrupt handler for the Xilinx FPGA on the 
+ * Big Sur board. These interrupts could be coming
+ * from the IDE, PCI, UART etc.
+ */
+void big_sur_irq_handler(struct pt_regs *regs)
+{
+	unsigned long reg_data;
+
+	reg_data = BIG_SUR_READ(BIG_SUR_INTERRUPT_STATUS_1);
+	
+	/* Now check for the UART 1 interrupts */
+	if (reg_data & 0x38)
+		do_IRQ(BIG_SUR_UART1_IRQ + BIG_SUR_IRQ_BASE, regs);
+
+	/* Now check for the UART 2 interrupts */
+	if (reg_data & 0x1c0)
+		do_IRQ(BIG_SUR_UART2_IRQ + BIG_SUR_IRQ_BASE, regs);
+
+	/* Now check for the Timer interrupt */
+	if (reg_data & 0x800)
+		do_IRQ(BIG_SUR_TIMER_IRQ + BIG_SUR_IRQ_BASE, regs);
+
+	/* Now check for the PCI interrupt, INTA */
+	if (reg_data & 0x2)
+		do_IRQ(BIG_SUR_PCI_IRQ + BIG_SUR_IRQ_BASE, regs);
+
+	/* Now check for the IDE interrupts */
+	if (reg_data & 0x1)
+		do_IRQ(BIG_SUR_IDE_IRQ + BIG_SUR_IRQ_BASE, regs);
+}
+
+#define	shutdown_big_sur_irq	disable_big_sur_irq
+
+struct hw_interrupt_type big_sur_irq_type = {
+	"BIG-SUR",
+	startup_big_sur_irq,
+	shutdown_big_sur_irq,
+	enable_big_sur_irq,
+	disable_big_sur_irq,
+	mask_and_ack_big_sur_irq,
+	end_big_sur_irq,
+	NULL
+};
+
+void big_sur_irq_init(void)
+{
+	int i;
+
+	/* Reset irq handlers pointers to NULL */
+	for (i = BIG_SUR_IRQ_BASE; i < (BIG_SUR_IRQ_BASE + 10); i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = 0;
+		irq_desc[i].depth = 2;
+		irq_desc[i].handler = &big_sur_irq_type;
+	}
+}
+
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/pmc-sierra/big_sur/int-handler.S linux-2.4.29-pre3/arch/mips/pmc-sierra/big_sur/int-handler.S
--- linux-2.4.28/arch/mips/pmc-sierra/big_sur/int-handler.S	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/pmc-sierra/big_sur/int-handler.S	2004-12-22 16:06:31.651486184 +0000
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2004 PMC-Sierra Inc. 
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * First-level interrupt dispatcher for the PMC-Sierra Big Sur board that
+ * has the Xilinx system controller.
+ *
+ * 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 <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+/*
+ * First level interrupt dispatcher for the Big Sur board
+ */
+		.align	5
+		NESTED(big_sur_handle_int, PT_SIZE, sp)
+		SAVE_ALL
+		CLI
+		.set	at
+		mfc0	t0, CP0_CAUSE  
+		mfc0	t2, CP0_STATUS
+
+		and	t0, t2
+        
+		andi	t1, t0, STATUSF_IP0	/* sw0 software interrupt */
+		bnez	t1, ll_sw0_irq
+		andi	t1, t0, STATUSF_IP1	/* sw1 software interrupt */
+		bnez	t1, ll_sw1_irq
+		andi	t1, t0, STATUSF_IP3	/* int1 hardware line */
+		bnez	t1, ll_xilinx_irq
+
+		.set	reorder
+
+		/* wrong alarm or masked ... */
+		j	spurious_interrupt
+		nop
+		END(big_sur_handle_int)
+
+		.align	5
+ll_sw0_irq:
+		li	a0, 0
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+ll_sw1_irq:
+		li	a0, 1
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+ll_xilinx_irq:
+		li	a0, 2
+		move	a1, sp
+		jal	big_sur_irq_handler
+		j	ret_from_irq
+		
+
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/pmc-sierra/big_sur/irq.c linux-2.4.29-pre3/arch/mips/pmc-sierra/big_sur/irq.c
--- linux-2.4.28/arch/mips/pmc-sierra/big_sur/irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/pmc-sierra/big_sur/irq.c	2004-12-22 16:06:47.463082456 +0000
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2003 PMC-Sierra Inc.
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <asm/bootinfo.h>
+#include <asm/mipsregs.h>
+
+static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED;
+
+extern asmlinkage void big_sur_handle_int(void);
+extern void big_sur_irq_init(void);
+
+void __init init_IRQ(void)
+{
+	/*
+	 * Clear all of the interrupts while we change the able around a bit.
+	 * int-handler is not on bootstrap
+	 */
+	clear_c0_status(ST0_IM);
+
+	/* Sets the first-level interrupt dispatcher. */
+	set_except_vector(0, big_sur_handle_int);
+	init_generic_irq();
+
+	mips_cpu_irq_init(0);
+	big_sur_irq_init();
+
+#ifdef CONFIG_REMOTE_DEBUG
+	printk("start kgdb ...\n");
+	set_debug_traps();
+	breakpoint();	/* you may move this line to whereever you want :-) */
+#endif
+#ifdef CONFIG_GDB_CONSOLE
+	register_gdb_console();
+#endif
+}
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/pmc-sierra/big_sur/prom.c linux-2.4.29-pre3/arch/mips/pmc-sierra/big_sur/prom.c
--- linux-2.4.28/arch/mips/pmc-sierra/big_sur/prom.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/pmc-sierra/big_sur/prom.c	2004-12-22 16:06:00.951153344 +0000
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2004 PMC-Sierra Inc.
+ * Author: Manish Lachwani (lachwani@pmc-sierra.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 <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+
+/* PMON Call Vectors */
+struct callvectors {
+int	(*open) (char*, int, int);
+int	(*close) (int);
+int	(*read) (int, void*, int);
+int	(*write) (int, void*, int);
+off_t	(*lseek) (int, off_t, int);
+int	(*printf) (const char*, ...);
+void	(*cacheflush) (void);
+char*	(*gets) (char*);
+};
+
+struct callvectors* debug_vectors;
+char arcs_cmdline[CL_SIZE];
+extern unsigned long cpu_clock;
+unsigned char big_sur_mac_addr_base[6] = "00:11:22:33:44:aa";
+
+const char *get_system_type(void)
+{
+	return "Big Sur";
+}
+
+void __init prom_init(int argc, char **arg, char **env, struct callvectors *cv)
+{
+	int i;
+
+	debug_vectors = cv;
+
+	/* PMON args begin with a g that stands for go */
+	arcs_cmdline[0] = '\0';
+	for (i = 1; i < argc; i++) {
+		if (strlen(arcs_cmdline) + strlen(arg[i] + 1)
+			>= sizeof(arcs_cmdline))
+				break;
+
+		strcat(arcs_cmdline, arg[i]);
+		strcat(arcs_cmdline, " ");
+	}
+
+	while (*env) {
+		if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0) {
+			cpu_clock = simple_strtol(*env + strlen("cpuclock="),
+						NULL, 10);
+		}
+		env++;
+	}
+
+	mips_machgroup = MACH_GROUP_PMC;
+	mips_machtype = MACH_PMC_BIG_SUR;
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
+
+void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
+{
+}
+	
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/pmc-sierra/big_sur/reset.c linux-2.4.29-pre3/arch/mips/pmc-sierra/big_sur/reset.c
--- linux-2.4.28/arch/mips/pmc-sierra/big_sur/reset.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/pmc-sierra/big_sur/reset.c	2004-12-22 16:07:42.026787512 +0000
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2004 PMC-Sierra Inc.
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <asm/processor.h>
+
+void big_sur_restart(char *command)
+{
+	/* FIXME: For now, fail regardless */
+	printk(KERN_NOTICE "Watchdog reset failed\n");
+}
+
+void big_sur_halt(void)
+{
+	printk(KERN_NOTICE "\n** You can safely turn off the power\n");
+	while (1)
+		__asm__(".set\tmips3\n\t"
+			"wait\n\t"
+			".set\tmips0");
+}
+
+void big_sur_power_off(void)
+{
+	big_sur_halt();
+}
+
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/pmc-sierra/big_sur/setup.c linux-2.4.29-pre3/arch/mips/pmc-sierra/big_sur/setup.c
--- linux-2.4.28/arch/mips/pmc-sierra/big_sur/setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/pmc-sierra/big_sur/setup.c	2004-12-22 16:07:10.349603176 +0000
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2004 PMC-Sierra Inc.
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/irq.h>
+#include <linux/time.h>
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+#include <asm/irq.h>
+#include <asm/processor.h>
+#include <asm/time.h>
+#include <asm/reboot.h>
+#include <asm/addrspace.h>
+
+#include "setup.h"
+
+unsigned long cpu_clock;
+
+extern void big_sur_restart(char *command);
+extern void big_sur_halt(void);
+extern void big_sur_power_off(void);
+
+void __init bus_error_init(void)
+{
+	/* Do Nothing */
+}
+
+void big_sur_timer_setup(struct irqaction *irq)
+{
+	/* Rm7000 timer and not the Xilinx timer */
+	setup_irq(7, irq);
+}
+
+#define	EPOCH		2000
+#define	BCD_TO_BIN(val)	(((val)&15) + ((val)>>4)*10)
+#define	BIN_TO_BCD(val)	((((val)/10)<<4) + (val)%10)
+
+static int rtc_ds_get_time(void)
+{
+	unsigned int year, month, day, hour, minute, second;
+	unsigned int century;
+
+	BIG_SUR_RTC_WRITE(0x40, 0x7f8);
+
+	second = BCD_TO_BIN(BIG_SUR_RTC_READ(0x7f8 + 1) & 0x7f);
+	minute = BCD_TO_BIN(BIG_SUR_RTC_READ(0x7f8 + 2));
+	hour = BCD_TO_BIN(BIG_SUR_RTC_READ(0x7f8 + 3));
+	day = BCD_TO_BIN(BIG_SUR_RTC_READ(0x7f8 + 5));
+	month = BCD_TO_BIN(BIG_SUR_RTC_READ(0x7f8 + 6));
+	year = BCD_TO_BIN(BIG_SUR_RTC_READ(0x7f8 + 7));
+	century = BCD_TO_BIN(BIG_SUR_RTC_READ(0x7f8) & 0x3f);
+
+	BIG_SUR_RTC_WRITE(0, 0x7f8);
+	year += century * 100;
+
+	return mktime(year, month, day, hour, minute, second);
+}
+
+extern void to_tm(unsigned long tim, struct rtc_time * tm);
+
+static int rtc_ds_set_time(unsigned long t)
+{
+	struct rtc_time tm;
+	u8 year, month, day, hour, minute, second;
+	u8 cmos_year, cmos_month, cmos_day, cmos_hour, cmos_minute, cmos_second;
+	int cmos_century;
+
+	BIG_SUR_RTC_WRITE(0x40, 0x7f8);
+	cmos_second = (u8)(BIG_SUR_RTC_READ(0x7f8 + 1) & 0x7f);
+	cmos_minute = (u8)(BIG_SUR_RTC_READ(0x7f8 + 2));
+	cmos_hour = (u8)(BIG_SUR_RTC_READ(0x7f8 + 3));
+	cmos_day = (u8)(BIG_SUR_RTC_READ(0x7f8 + 4));
+	cmos_month = (u8)(BIG_SUR_RTC_READ(0x7f8 + 6));
+	cmos_year = (u8)(BIG_SUR_RTC_READ(0x7f8 + 7));
+	cmos_century = BIG_SUR_RTC_READ(0x7f8) & 0x3f;
+
+	BIG_SUR_RTC_WRITE(0x80, 0x7f8);
+
+	to_tm(t, &tm);
+	
+	year = BIN_TO_BCD(tm.tm_year - EPOCH);
+	if (year != cmos_year) {
+		BIG_SUR_RTC_WRITE(year, (0x7f8 + 7));
+	}
+
+	month = BIN_TO_BCD(tm.tm_mon);
+	if (month != (cmos_month & 0x1f)) {
+		BIG_SUR_RTC_WRITE((month & 0x1f) | (cmos_month & ~0x1f), (0x7f8 + 6));	
+	}
+
+	day = BIN_TO_BCD(tm.tm_mday);
+	if (day != cmos_day) {
+		BIG_SUR_RTC_WRITE(day, (0x7f8 + 5));
+	}
+
+	if (cmos_hour & 0x40) {
+		hour = 0x40;
+		if (tm.tm_hour > 12) {
+			hour |= 0x20 | (BIN_TO_BCD(hour - 12) & 0x1f);
+		}
+		else {
+			hour |= BIN_TO_BCD(tm.tm_hour);
+		}
+	}
+	else {
+		hour = BIN_TO_BCD(tm.tm_hour) & 0x3f;
+	}
+
+	if (hour != cmos_hour) {
+		BIG_SUR_RTC_WRITE(hour, (0x7f8 + 3));
+	}
+
+	minute = BIN_TO_BCD(tm.tm_min);
+	if (minute !=  cmos_minute) {
+		BIG_SUR_RTC_WRITE(minute, (0x7f8 + 2));
+	}
+
+	second = BIN_TO_BCD(tm.tm_sec);
+	if (second !=  cmos_second) {
+		BIG_SUR_RTC_WRITE(second, (0x7f8 + 1));
+	}
+
+	BIG_SUR_RTC_WRITE(cmos_century, 0x7f8);
+
+	return 0;
+}
+
+void rtc_init(void)
+{
+	u8 seconds;
+
+	/* set the function pointers */
+	rtc_get_time = rtc_ds_get_time;
+	rtc_set_time = rtc_ds_set_time;
+
+	BIG_SUR_RTC_WRITE(0x40, 0x7f8);
+	seconds = (u8)(BIG_SUR_RTC_READ(0x7f8 + 1) & 0x7f);
+	BIG_SUR_RTC_WRITE(0x80, 0x7f8);
+	BIG_SUR_RTC_WRITE(seconds, (0x7f8 + 1));
+	BIG_SUR_RTC_WRITE(0, 0x7f8);
+}
+
+void big_sur_time_init(void)
+{
+	mips_counter_frequency = cpu_clock / 2;
+	board_timer_setup = big_sur_timer_setup;
+
+	/* 
+	 * The RTC device off the Xilinx System Controller
+	 * is the DS1742
+	 */
+	
+	rtc_init();
+}
+
+void __init pmc_big_sur_setup(void)
+{
+	board_time_init = big_sur_time_init;
+
+	_machine_restart = big_sur_restart;
+	_machine_halt = big_sur_halt;
+	_machine_power_off = big_sur_power_off;
+
+	printk("PMC-Sierra Big Sur Board \n");
+
+	/* Add 256 MB. Thats all it can support */
+	add_memory_region(0x00000000, 0x10000000, BOOT_MEM_RAM);
+
+	/* Configure the IDE interface, if needed */
+#ifdef	CONFIG_BLK_DEV_IDE_BIG_SUR
+	/* 
+	 * ATA Timing register, sample IORDY. The device operates
+	 * in PIO 0 mode and the slave device is disabled
+	 */
+	*(volatile u_int32_t *)((KSEG1ADDR(0x1B300000)) + 0x40) = 0x2;
+#endif
+}
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/pmc-sierra/big_sur/xilinx_irq.h linux-2.4.29-pre3/arch/mips/pmc-sierra/big_sur/xilinx_irq.h
--- linux-2.4.28/arch/mips/pmc-sierra/big_sur/xilinx_irq.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/pmc-sierra/big_sur/xilinx_irq.h	2004-12-22 16:06:39.366313352 +0000
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2003 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * Board specific definititions for the PMC-Sierra Big Sur
+ *
+ * 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 __XILINX_IRQ_H__
+#define	__XILINX_IRQ_H__
+
+#define BIG_SUR_BASE	0xfb000000
+
+#define BIG_SUR_WRITE(ofs, data)	\
+	*(volatile u32 *)(BIG_SUR_BASE + ofs) = data
+
+#define BIG_SUR_READ(ofs)	*(volatile u32 *)(BIG_SUR_BASE + ofs)
+
+#define	BIG_SUR_INTERRUPT_MASK_1	0x0c00
+#define	BIG_SUR_INTERRUPT_STATUS_1	0x0d00
+#define	BIG_SUR_UART1_IRQ
+#define	BIG_SUR_UART2_IRQ
+#define	BIG_SUR_TIMER_IRQ
+#define	BIG_SUR_PCI_IRQ
+#define	BIG_SUR_IDE_IRQ
+
+#endif
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/pmc-sierra/stretch/Makefile linux-2.4.29-pre3/arch/mips/pmc-sierra/stretch/Makefile
--- linux-2.4.28/arch/mips/pmc-sierra/stretch/Makefile	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/pmc-sierra/stretch/Makefile	2004-12-22 16:07:11.204473216 +0000
@@ -0,0 +1,18 @@
+#
+# Makefile for PMC-Sierra Stretch Board
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET:= stretch.o
+
+obj-y	 += prom.o reset.o setup.o irq-handler.o irq.o
+
+obj-$(CONFIG_PCI)	   += pci-irq.o pci.o
+obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o
+
+include $(TOPDIR)/Rules.make
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/pmc-sierra/stretch/dbg_io.c linux-2.4.29-pre3/arch/mips/pmc-sierra/stretch/dbg_io.c
--- linux-2.4.28/arch/mips/pmc-sierra/stretch/dbg_io.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/pmc-sierra/stretch/dbg_io.c	2004-12-22 16:05:31.296661512 +0000
@@ -0,0 +1,164 @@
+/*
+ *  PMC-Sierra Inc. Stretch Board
+ *  Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  KGDB support for the PMC-Sierra Stretch board
+ *
+ */
+
+#include <linux/config.h>
+
+#if defined(CONFIG_REMOTE_DEBUG)
+
+#include <asm/serial.h> /* For the serial port location and base baud */
+
+
+typedef unsigned char uint8;
+typedef unsigned int uint32;
+
+/*
+ * Baud rate
+ */
+#define         UART16550_BAUD_2400             2400
+#define         UART16550_BAUD_4800             4800
+#define         UART16550_BAUD_9600             9600
+#define         UART16550_BAUD_19200            19200
+#define         UART16550_BAUD_38400            38400
+#define         UART16550_BAUD_57600            57600
+#define         UART16550_BAUD_115200           115200
+
+/*
+ * Parity bit 
+ */
+#define         UART16550_PARITY_NONE           0
+#define         UART16550_PARITY_ODD            0x08
+#define         UART16550_PARITY_EVEN           0x18
+#define         UART16550_PARITY_MARK           0x28
+#define         UART16550_PARITY_SPACE          0x38
+
+/*
+ * Data bit
+ */
+#define         UART16550_DATA_5BIT             0x0
+#define         UART16550_DATA_6BIT             0x1
+#define         UART16550_DATA_7BIT             0x2
+#define         UART16550_DATA_8BIT             0x3
+
+/*
+ * Stop bit
+ */
+#define         UART16550_STOP_1BIT             0x0
+#define         UART16550_STOP_2BIT             0x4
+
+/*
+ * Serial port defines
+ */
+#define         BASE                    PMC_STRETCH_SERIAL1_BASE
+#define         MAX_BAUD                PMC_STRETCH_BASE_BAUD
+
+
+#define         REG_OFFSET              2
+
+/* 
+ * register offset 
+ */
+#define         OFS_RCV_BUFFER          0
+#define         OFS_TRANS_HOLD          0
+#define         OFS_SEND_BUFFER         0
+#define         OFS_INTR_ENABLE         (1*REG_OFFSET)
+#define         OFS_INTR_ID             (2*REG_OFFSET)
+#define         OFS_DATA_FORMAT         (3*REG_OFFSET)
+#define         OFS_LINE_CONTROL        (3*REG_OFFSET)
+#define         OFS_MODEM_CONTROL       (4*REG_OFFSET)
+#define         OFS_RS232_OUTPUT        (4*REG_OFFSET)
+#define         OFS_LINE_STATUS         (5*REG_OFFSET)
+#define         OFS_MODEM_STATUS        (6*REG_OFFSET)
+#define         OFS_RS232_INPUT         (6*REG_OFFSET)
+#define         OFS_SCRATCH_PAD         (7*REG_OFFSET)
+
+#define         OFS_DIVISOR_LSB         (0*REG_OFFSET)
+#define         OFS_DIVISOR_MSB         (1*REG_OFFSET)
+
+
+/* 
+ * memory-mapped read/write of the port 
+ */
+#define         UART16550_READ(y)    (*((volatile uint8*)(BASE + y)))
+#define         UART16550_WRITE(y, z)  ((*((volatile uint8*)(BASE + y))) = z)
+
+void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop)
+{
+	/* disable interrupts */
+	UART16550_WRITE(OFS_INTR_ENABLE, 0);
+
+	/* set up buad rate */
+	{
+		uint32 divisor;
+
+		/* set DIAB bit */
+		UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
+
+		/* set divisor */
+		divisor = MAX_BAUD / baud;
+		UART16550_WRITE(OFS_DIVISOR_LSB, divisor & 0xff);
+		UART16550_WRITE(OFS_DIVISOR_MSB, (divisor & 0xff00) >> 8);
+
+		/* clear DIAB bit */
+		UART16550_WRITE(OFS_LINE_CONTROL, 0x0);
+	}
+
+	/* set data format */
+	UART16550_WRITE(OFS_DATA_FORMAT, data | parity | stop);
+}
+
+static int remoteDebugInitialized = 0;
+
+uint8 getDebugChar(void)
+{
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(UART16550_BAUD_38400,
+			  UART16550_DATA_8BIT,
+			  UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+	}
+
+	while ((UART16550_READ(OFS_LINE_STATUS) & 0x1) == 0);
+	return UART16550_READ(OFS_RCV_BUFFER);
+}
+
+
+int putDebugChar(uint8 byte)
+{
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(UART16550_BAUD_38400,
+			  UART16550_DATA_8BIT,
+			  UART16550_PARITY_NONE, UART16550_STOP_1BIT);
+	}
+
+	while ((UART16550_READ(OFS_LINE_STATUS) & 0x20) == 0);
+	UART16550_WRITE(OFS_SEND_BUFFER, byte);
+	return 1;
+}
+
+#endif
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/pmc-sierra/stretch/irq-handler.S linux-2.4.29-pre3/arch/mips/pmc-sierra/stretch/irq-handler.S
--- linux-2.4.28/arch/mips/pmc-sierra/stretch/irq-handler.S	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/pmc-sierra/stretch/irq-handler.S	2004-12-22 16:06:58.451411976 +0000
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2004 PMC-Sierra Inc.
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * First-level interrupt dispatcher for the PMC-Sierra Stretch Board
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#define __ASSEMBLY__
+#include <linux/config.h>
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+/*
+ * First level interrupt dispatcher for the PMC-Sierra Stretch Board
+ */
+
+		.align	5
+		NESTED(pmc_stretch_handle_int, PT_SIZE, sp)
+		SAVE_ALL
+		CLI
+		.set	at
+
+		mfc0	t0, CP0_CAUSE
+		mfc0	t2, CP0_STATUS
+
+		and	t0, t2
+
+		andi	t1, t0, STATUSF_IP0	/* sw0 software interrupt */
+		bnez	t1, ll_sw0_irq
+
+		andi	t1, t0, STATUSF_IP1	/* sw1 software interrupt */
+		bnez	t1, ll_sw1_irq
+
+		andi	t1, t0, STATUSF_IP7	/* Rm7000 CPU timer */
+		bnez	t1, ll_timer_irq
+
+		.set	reorder
+
+		/* wrong alarm or masked ... */
+		j	spurious_interrupt
+		nop
+		END(pmc_stretch_handle_int)
+
+		.align	5
+
+ll_sw0_irq:
+		li	a0, 1
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_sw1_irq:
+		li	a0, 2
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+ll_timer_irq:
+		li	a0, 8
+		move	a1, sp
+		jal	do_IRQ
+		j	ret_from_irq
+
+			
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/pmc-sierra/stretch/irq.c linux-2.4.29-pre3/arch/mips/pmc-sierra/stretch/irq.c
--- linux-2.4.28/arch/mips/pmc-sierra/stretch/irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/pmc-sierra/stretch/irq.c	2004-12-22 16:07:21.990833440 +0000
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2003 PMC-Sierra Inc.
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <asm/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED;
+
+#ifdef CONFIG_KGDB
+extern void breakpoint(void);
+extern void set_debug_traps(void);
+#endif
+
+extern asmlinkage void pmc_stretch_handle_int(void);
+
+void __init init_IRQ(void)
+{
+	int i;
+
+	clear_c0_status(ST0_IM | ST0_BEV);
+	__cli();
+
+	set_except_vector(0, pmc_stretch_handle_int);
+	init_generic_irq();
+	mips_cpu_irq_init(0);
+
+#ifdef CONFIG_KGDB
+	printk("start kgdb ...\n");
+	set_debug_traps();
+
+	breakpoint();
+#endif
+
+#ifdef CONFIG_GDB_CONSOLE
+	register_gdb_console();
+#endif
+}
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/pmc-sierra/stretch/pci-irq.c linux-2.4.29-pre3/arch/mips/pmc-sierra/stretch/pci-irq.c
--- linux-2.4.28/arch/mips/pmc-sierra/stretch/pci-irq.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/pmc-sierra/stretch/pci-irq.c	2004-12-22 16:07:43.596548872 +0000
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2004 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <asm/pci.h>
+
+void __init pmc_stretch_pcibios_fixup_bus(struct pci_bus *bus)
+{
+	struct pci_bus *current_bus = bus;
+	struct pci_dev *devices;
+	struct list_head *devices_link;
+
+	list_for_each(devices_link, &(current_bus->devices)) {
+		devices = pci_dev_b(devices_link);
+
+		if (devices == NULL)
+			continue;
+
+		devices->irq = 7; /* FIXME */
+	}
+}
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/pmc-sierra/stretch/pci.c linux-2.4.29-pre3/arch/mips/pmc-sierra/stretch/pci.c
--- linux-2.4.28/arch/mips/pmc-sierra/stretch/pci.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/pmc-sierra/stretch/pci.c	2004-12-22 16:07:38.109383048 +0000
@@ -0,0 +1,336 @@
+/*
+ * Copyright 2004 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  PCI interface for the PMC-Sierra Stretch Board
+ */
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+
+#include <asm/pci.h>
+#include <asm/io.h>
+
+#include "setup.h"
+
+#ifdef CONFIG_PCI
+
+void pmc_stretch_pcibios_fixup_bus(struct pci_bus* c);
+
+static int pmc_stretch_read_config_dword(struct pci_dev *device,
+					int offset, u32* val)
+{
+	int dev, bus, func;
+	uint32_t address;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+	func = PCI_FUNC(device->devfn);
+
+	address = (bus << 8) | (dev << 16) | (func << 21) |
+		((offset & 0xfc) << 24)  | 0x1;
+
+	PMC_STRETCH_WRITE(PMC_STRETCH_PCI_0_CONFIG_ADDRESS, address);
+	PMC_STRETCH_READ(PMC_STRETCH_PCI_0_DATA_ADDRESS, val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int pmc_stretch_read_config_word(struct pci_dev *device,
+					int offset, u16* val)
+{
+	int dev, bus, func;
+	uint32_t address;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+	func = PCI_FUNC(device->devfn);
+
+	address = (bus << 8) | (dev << 16) | (func << 21) |
+		((offset & 0xfc) << 24)  | 0x1;
+
+	PMC_STRETCH_WRITE(PMC_STRETCH_PCI_0_CONFIG_ADDRESS, address);
+	PMC_STRETCH_READ_16((PMC_STRETCH_PCI_0_DATA_ADDRESS + (offset & 0x3)), val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int pmc_stretch_read_config_byte(struct pci_dev *device,
+					int offset, u8* val)
+{
+	int dev, bus, func;
+	uint32_t address;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+	func = PCI_FUNC(device->devfn);
+
+	address = (bus << 8) | (dev << 16) | (func << 21) |
+		((offset & 0xfc) << 24)  | 0x1;
+
+	PMC_STRETCH_WRITE(PMC_STRETCH_PCI_0_CONFIG_ADDRESS, address);
+	PMC_STRETCH_READ_8((PMC_STRETCH_PCI_0_DATA_ADDRESS + (offset & 0x3)), val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int pmc_stretch_write_config_dword(struct pci_dev *device,
+					int offset, u32 val)
+{
+	int dev, bus, func;
+	uint32_t address;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+	func = PCI_FUNC(device->devfn);
+
+	address = (bus << 8) | (dev << 16) | (func << 21) |
+		((offset & 0xfc) << 24)  | 0x1;
+
+	PMC_STRETCH_WRITE(PMC_STRETCH_PCI_0_CONFIG_ADDRESS, address);
+	PMC_STRETCH_WRITE(PMC_STRETCH_PCI_0_DATA_ADDRESS, val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int pmc_stretch_write_config_word(struct pci_dev *device,
+					int offset, u16 val)
+{
+	int dev, bus, func;
+	uint32_t address;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+	func = PCI_FUNC(device->devfn);
+
+	address = (bus << 8) | (dev << 16) | (func << 21) |
+		((offset & 0xfc) << 24)  | 0x1;
+
+	PMC_STRETCH_WRITE(PMC_STRETCH_PCI_0_CONFIG_ADDRESS, address);
+	PMC_STRETCH_WRITE_16((PMC_STRETCH_PCI_0_DATA_ADDRESS + (offset & 0x3)), val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int pmc_stretch_write_config_byte(struct pci_dev *device,
+					int offset, u8 val)
+{
+	int dev, bus, func;
+	uint32_t address;
+
+	bus = device->bus->number;
+	dev = PCI_SLOT(device->devfn);
+	func = PCI_FUNC(device->devfn);
+
+	address = (bus << 8) | (dev << 16) | (func << 21) |
+		((offset & 0xfc) << 24)  | 0x1;
+
+	PMC_STRETCH_WRITE(PMC_STRETCH_PCI_0_CONFIG_ADDRESS, address);
+	PMC_STRETCH_WRITE_8((PMC_STRETCH_PCI_0_DATA_ADDRESS + (offset & 0x3)), val);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static void pmc_stretch_pcibios_set_master(struct pci_dev *dev)
+{
+	u16 cmd;
+
+	pmc_stretch_read_config_word(dev, PCI_COMMAND, &cmd);
+	cmd |= PCI_COMMAND_MASTER;
+	pmc_stretch_write_config_word(dev, PCI_COMMAND, cmd);
+}
+
+int pcibios_enable_resources(struct pci_dev *dev)
+{
+	u16 cmd, old_cmd;
+	u8 tmp1;
+	int idx;
+	struct resource *r;
+
+	pmc_stretch_read_config_word(dev, PCI_COMMAND, &cmd);
+	
+	old_cmd = cmd;
+	for (idx = 0; idx < 6; idx++) {
+		r = &dev->resource[idx];
+		if (!r->start && r->end) {
+			printk(KERN_ERR
+				"PCI: Device %s not available because of "
+				"resource collisions\n", dev->slot_name);
+
+			return -EINVAL;
+		}
+
+		if (r->flags & IORESOURCE_IO)
+			cmd |= PCI_COMMAND_IO;
+
+		if (r->flags & IORESOURCE_MEM)
+			cmd |= PCI_COMMAND_MEMORY;
+	}
+
+	if (cmd != old_cmd) 
+		pmc_stretch_write_config_word(dev, PCI_COMMAND, cmd);
+
+	pmc_stretch_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &tmp1);
+	if (tmp1 != 8) {
+		printk(KERN_WARNING "PCI setting cache line size to 8 from "
+			"%d\n", tmp1);
+	
+		pmc_stretch_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 8);
+	}
+
+	pmc_stretch_read_config_byte(dev, PCI_LATENCY_TIMER, &tmp1);
+	if (tmp1 < 32 || tmp1 == 0xff) {
+		printk(KERN_WARNING "PCI setting latency timer to 32 from %d\n",
+			tmp1);
+		pmc_stretch_write_config_byte(dev, PCI_LATENCY_TIMER, 32);
+	}
+
+	return 0;
+}
+
+/*
+ * Export for pcibios_enable_device
+ */
+int pcibios_enable_device(struct pci_dev *dev, int mask)
+{
+	return pcibios_enable_resources(dev);
+}
+
+/*
+ * Export for pcibios_update_resource
+ */
+void pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+				struct resource *res, int resource)
+{
+	u32 new, check;
+	int reg;
+
+	new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
+	if (resource < 6) {
+		reg = PCI_BASE_ADDRESS_0 + 4 * resource;
+	} else if (resource == PCI_ROM_RESOURCE) {
+		res->flags |= PCI_ROM_ADDRESS_ENABLE;
+		reg = dev->rom_base_reg;
+	} else {
+		/*
+		 * Somebody might have asked allocation of a non-standard
+		 * resource
+		 */
+		return;
+	}
+
+	pci_write_config_dword(dev, reg, new);
+	pci_read_config_dword(dev, reg, &check);
+	if ((new ^ check) &
+		((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK :
+			PCI_BASE_ADDRESS_MEM_MASK)) {
+				printk(KERN_ERR "PCI: Error while updating region "
+					"%s/%d (%08x != %08x)\n", dev->slot_name, resource,
+					new, check);
+	}
+}
+
+/*
+ * Export to pcibios_align_resource
+ */
+void pcibios_align_resource(void *data, struct resource *res,
+                            unsigned long size, unsigned long align)
+{
+	struct pci_dev *dev = data;
+
+	if (res->flags & IORESOURCE_IO) {
+		unsigned long start = res->start;
+
+		/* 
+		 * We need to avoid collisions with `mirrored' VGA ports
+		 * and other strange ISA hardware, so we always want the
+		 * addresses kilobyte aligned.  
+		 */
+		if (size > 0x100) {
+			printk(KERN_ERR "PCI: I/O Region %s/%d too large"
+					" (%ld bytes)\n", dev->slot_name,
+					dev->resource - res, size);
+		}
+
+		start = (start + 1024 - 1) & ~(1024 - 1);
+		res->start = start;
+	}
+}
+
+struct pci_ops pmc_stretch_pci_ops = {
+	pmc_stretch_read_config_byte,
+	pmc_stretch_read_config_word,
+	pmc_stretch_read_config_dword,
+	pmc_stretch_write_config_byte,
+	pmc_stretch_write_config_word,
+	pmc_stretch_write_config_dword
+};
+
+struct pci_fixup pcibios_fixups[] = {
+	{0}
+};
+
+void __init pcibios_fixup_bus(struct pci_bus *c)
+{
+	pmc_stretch_pcibios_fixup_bus(c);
+}
+
+void __init pcibios_init(void)
+{
+	/*
+	 * FIXME: Values to change once PMON configures the 
+	 * IO and MEM space for the PCI devices
+	 */
+	ioport_resource.start = 0xe0000000;
+	ioport_resource.end   = 0xe0000000 + 0x20000000 - 1;
+	iomem_resource.start  = 0xc0000000;
+	iomem_resource.end    = 0xc0000000 + 0x20000000 - 1;
+
+	/*
+	 * PMC-Sierra Stretch has only two PCI busses. Scan them now
+	 */
+	pci_scan_bus(0, &pmc_stretch_pci_ops, NULL);
+	pci_scan_bus(1, &pmc_stretch_pci_ops, NULL);
+}
+
+/*
+ * for parsing "pci=" kernel boot arguments.
+ */
+char *pcibios_setup(char *str)
+{
+	printk(KERN_INFO "rr: pcibios_setup\n");
+	/* Nothing to do for now.  */
+
+	return str;
+}
+
+unsigned int pcibios_assign_all_busses(void)
+{
+	return 1;
+}
+
+#endif
+
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/pmc-sierra/stretch/prom.c linux-2.4.29-pre3/arch/mips/pmc-sierra/stretch/prom.c
--- linux-2.4.28/arch/mips/pmc-sierra/stretch/prom.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/pmc-sierra/stretch/prom.c	2004-12-22 16:07:31.928322712 +0000
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2004 PMC-Sierra Inc.
+ * Author : Manish Lachwani (lachwani@pmc-sierra.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 <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/bootmem.h>
+
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+
+/*
+ * PMON Callvectors
+ */
+struct callvectors {
+	int	(*open) (char*, int, int);
+	int	(*close) (int);
+	int	(*read) (int, void*, int);
+	int	(*write) (int, void*, int);
+	off_t	(*lseek) (int, off_t, int);
+	int	(*printf) (const char*, ...);
+	void	(*cacheflush) (void);
+	char*	(*gets) (char*);
+};
+
+struct callvectors* debug_vectors;
+char arcs_cmdline[CL_SIZE];
+
+extern unsigned long cpu_clock;
+
+/*
+ * Board Type 
+ */
+const char *get_system_type(void)
+{
+	return "PMC-Sierra Stretch";
+}
+
+#ifdef CONFIG_MIPS64
+
+unsigned long signext(unsigned long addr)
+{
+  addr &= 0xffffffff;
+  return (unsigned long)((int)addr);
+}
+
+void *get_arg(unsigned long args, int arc)
+{
+  unsigned long ul;
+  unsigned char *puc, uc;
+
+  args += (arc * 4);
+  ul = (unsigned long)signext(args);
+  puc = (unsigned char *)ul;
+  if (puc == 0)
+    return (void *)0;
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+  uc = *puc++;
+  ul = (unsigned long)uc;
+  uc = *puc++;
+  ul |= (((unsigned long)uc) << 8);
+  uc = *puc++;
+  ul |= (((unsigned long)uc) << 16);
+  uc = *puc++;
+  ul |= (((unsigned long)uc) << 24);
+#else  /* CONFIG_CPU_LITTLE_ENDIAN */
+  uc = *puc++;
+  ul = ((unsigned long)uc) << 24;
+  uc = *puc++;
+  ul |= (((unsigned long)uc) << 16);
+  uc = *puc++;
+  ul |= (((unsigned long)uc) << 8);
+  uc = *puc++;
+  ul |= ((unsigned long)uc);
+#endif  /* CONFIG_CPU_LITTLE_ENDIAN */
+  ul = signext(ul);
+  return (void *)ul;
+}
+
+char *arg64(unsigned long addrin, int arg_index)
+{
+  unsigned long args;
+  char *p;
+  args = signext(addrin);
+  p = (char *)get_arg(args, arg_index);
+  return p;
+}
+#endif  /* CONFIG_MIPS64 */
+
+
+/* PMON passes arguments in C main() style */
+void __init prom_init(int argc, char **arg, char **env, struct callvectors *cv)
+{
+	int i;
+#ifdef CONFIG_MIPS64
+	char *ptr;
+
+	printk("prom_init - MIPS64\n");
+
+	/* save the PROM vectors for debugging use */
+	debug_vectors = (struct callvectors *)signext((unsigned long)cv);
+
+	/* arg[0] is "g", the rest is boot parameters */
+	arcs_cmdline[0] = '\0';
+
+	for (i = 1; i < argc; i++) {
+		ptr = (char *)arg64((unsigned long)arg, i);
+		if ((strlen(arcs_cmdline) + strlen(ptr) + 1) >=
+		    sizeof(arcs_cmdline))
+			break;
+		strcat(arcs_cmdline, ptr);
+		strcat(arcs_cmdline, " ");
+	}
+	i = 0;
+
+	while (1) {
+		ptr = (char *)arg64((unsigned long)env, i);
+		if (! ptr)
+			break;
+
+		if (strncmp("cpuclock", ptr, strlen("cpuclock")) == 0) {
+			cpu_clock = simple_strtol(ptr + strlen("cpuclock="),
+							NULL, 10);
+			printk("cpu_clock set to %d\n", cpu_clock);
+		}
+		i++;
+	}
+	printk("arcs_cmdline: %s\n", arcs_cmdline);
+
+#else   /* CONFIG_MIPS64 */
+
+	/* save the PROM vectors for debugging use */
+	debug_vectors = cv;
+
+	/* arg[0] is "g", the rest is boot parameters */
+	arcs_cmdline[0] = '\0';
+	for (i = 1; i < argc; i++) {
+		if (strlen(arcs_cmdline) + strlen(arg[i] + 1)
+		    >= sizeof(arcs_cmdline))
+			break;
+		strcat(arcs_cmdline, arg[i]);
+		strcat(arcs_cmdline, " ");
+	}
+
+	while (*env) {
+		if (strncmp("cpuclock", *env, strlen("cpuclock")) == 0) {
+			cpu_clock = simple_strtol(*env + strlen("cpuclock="),
+							NULL, 10);
+		}
+		env++;
+	}
+#endif /* CONFIG_MIPS64 */
+
+	mips_machgroup = MACH_GROUP_PMC;
+	mips_machtype = MACH_PMC_STRETCH;
+
+#ifndef CONFIG_MIPS64
+
+	/* 
+	 * This proves that the basic interaction between PMON
+	 * and Linux is working. At this point, Linux has taken
+	 * control. Note that the early printk patch at this point
+	 * is very useful since it directly interacts with the 
+	 * serial console. 
+	 */
+	debug_vectors->printf("Booting Linux kernel...\n");
+#endif
+}
+
+void __init prom_free_prom_memory(void)
+{
+	/* Do nothing */
+}
+
+void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
+{
+	/* Do nothing */
+}
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/pmc-sierra/stretch/reset.c linux-2.4.29-pre3/arch/mips/pmc-sierra/stretch/reset.c
--- linux-2.4.28/arch/mips/pmc-sierra/stretch/reset.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/pmc-sierra/stretch/reset.c	2004-12-22 16:06:19.757294376 +0000
@@ -0,0 +1,44 @@
+/*
+ * Copyright PMC-Sierra Inc. 
+ * Author : Manish Lachwani (lachwani@pmc-sierra.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 <asm/io.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+#include <linux/delay.h>
+#include "setup.h"
+
+void pmc_stretch_restart(char *command)
+{
+	/* base address of timekeeper portion of part */
+	void *nvram = (void *)PMC_STRETCH_NVRAM_BASE;
+
+ 	/* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */
+	writeb(0x84, nvram + 0xff7);
+
+	/* wait for the watchdog to go off */
+	mdelay(100+(1000/16));
+
+	/* if the watchdog fails for some reason, let people know */
+	printk(KERN_NOTICE "Watchdog reset failed\n");
+}
+
+void pmc_stretch_halt(void)
+{
+	printk(KERN_NOTICE "\n** You can safely turn off the power\n");
+	while (1)
+		__asm__(".set\tmips3\n\t"
+	                "wait\n\t"
+			".set\tmips0");
+}
+
+void pmc_stretch_power_off(void)
+{
+	pmc_stretch_halt();
+}
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/pmc-sierra/stretch/setup.c linux-2.4.29-pre3/arch/mips/pmc-sierra/stretch/setup.c
--- linux-2.4.28/arch/mips/pmc-sierra/stretch/setup.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/pmc-sierra/stretch/setup.c	2004-12-22 16:06:24.894513400 +0000
@@ -0,0 +1,107 @@
+/*
+ *  PMC-Sierra Inc. Stretch Board 
+ *  Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *  Setup for the PMC-Sierra Stretch board. Stretch makes processors that are
+ *  based off the Xtensa core. 
+ *
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <asm/time.h>
+#include <asm/page.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/reboot.h>
+#include <linux/version.h>
+#include <linux/bootmem.h>
+#include "setup.h"
+
+unsigned long cpu_clock;
+
+extern void pmc_stretch_restart(char *command);
+extern void pmc_stretch_halt(void);
+extern void pmc_stretch_power_off(void);
+
+/* These functions are used for rebooting or halting the machine*/
+extern void pmc_stretch_restart(char *command);
+extern void pmc_stretch_halt(void);
+extern void pmc_stretch_off(void);
+
+void pmc_stretch_time_init(void);
+
+void __init bus_error_init(void) 
+{
+	/* Do nothing */ 
+}
+
+/* setup code for a handoff from a version 2 PMON 2000 PROM */
+void PMON_v2_setup(void)
+{
+	printk("PMON_v2_setup\n");
+
+}
+
+/* Setup the timer interrupt */
+void pmc_stretch_timer_setup(struct irqaction *irq)
+{
+	setup_irq(8, irq);
+}
+
+/* FIXME: get_time and set_time routines */
+void pmc_stretch_time_init(void)
+{
+	mips_counter_frequency = cpu_clock / 2;
+	printk("pmc_stretch_time_init cpu_clock=%d\n", cpu_clock);
+	board_timer_setup = pmc_stretch_timer_setup;
+
+}
+
+/* Board Setup */
+void __init pmc_stretch_setup(void)
+{
+	unsigned int tmpword;
+
+	board_time_init = pmc_stretch_time_init;
+
+	_machine_restart = pmc_stretch_restart;
+	_machine_halt = pmc_stretch_halt;
+	_machine_power_off = pmc_stretch_power_off;
+
+	/* do handoff reconfiguration */
+	PMON_v2_setup();
+
+	printk("CPU : Rm7000 \n");
+
+	/* 128 MB */
+	printk("  - SDRAM size: 128 MB\n");
+	add_memory_region(0x0, 0x08000000, BOOT_MEM_RAM);
+}
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/pmc-sierra/stretch/setup.h linux-2.4.29-pre3/arch/mips/pmc-sierra/stretch/setup.h
--- linux-2.4.28/arch/mips/pmc-sierra/stretch/setup.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/pmc-sierra/stretch/setup.h	2004-12-22 16:07:06.389205248 +0000
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2004 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * Board specific definititions for the PMC-Sierra Stretch
+ *
+ * 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 __SETUP_H__
+#define __SETUP_H__
+
+/* 
+ * Define for the base addreses 
+ */
+
+#define	PMC_STRETCH_BASE			(0x1A000000 + KSEG1) /* FIXME */
+
+/* 
+ * PCI defines
+ */
+#define	PMC_STRETCH_PCI_BASE			(0x1A000000 + KSEG1) /* FIXME */
+
+#define	PMC_STRETCH_READ_DATA(ofs)				\
+	*(volatile u32 *)(PMC_STRETCH_PCI_BASE + ofs)
+
+/*
+ * PCI Config space accesses
+ */
+#define	PMC_STRETCH_PCI_0_CONFIG_ADDRESS	0x678
+#define	PMC_STRETCH_PCI_0_DATA_ADDRESS		0x6fc
+
+#define	PMC_STRETCH_WRITE(ofs, data)				\
+	*(volatile u32 *)(PMC_STRETCH_PCI_BASE + ofs) = data
+
+#define	PMC_STRETCH_READ(ofs, data)				\
+	*(data) = *(volatile u32 *)(PMC_STRETCH_PCI_BASE + ofs)
+
+#define	PMC_STRETCH_WRITE_16(ofs, data)				\
+	*(volatile u16 *)(PMC_STRETCH_PCI_BASE + ofs) = data
+
+#define	PMC_STRETCH_READ_16(ofs, data)				\
+	*(data) =  *(volatile u16 *)(PMC_STRETCH_PCI_BASE + ofs)
+
+#define	PMC_STRETCH_WRITE_8(ofs, data)				\
+	*(volatile u8 *)(PMC_STRETCH_PCI_BASE + ofs) = data
+
+#define	PMC_STRETCH_READ_8(ofs, data)				\
+	*(data) = *(volatile u8 *)(PMC_STRETCH_PCI_BASE + ofs)
+
+/* 
+ * RTC/NVRAM 
+ */
+#define	PMC_STRETCH_NVRAM_BASE	0xfc800000	/* FIXME */
+
+#endif /* __SETUP_H__ */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/pmc-sierra/yosemite/Makefile linux-2.4.29-pre3/arch/mips/pmc-sierra/yosemite/Makefile
--- linux-2.4.28/arch/mips/pmc-sierra/yosemite/Makefile	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/pmc-sierra/yosemite/Makefile	2004-12-22 16:07:36.080691456 +0000
@@ -2,15 +2,13 @@
 # Makefile for the PMC-Sierra Titan 
 #
 
-.S.s:
-	$(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
-	$(CC) $(CFLAGS) -c $< -o $*.o
+USE_STANDARD_AS_RULE := true
 
 O_TARGET:= titan.o
 
 obj-y    += irq-handler.o irq.o i2c-yosemite.o prom.o setup.o
 
+obj-$(CONFIG_KGDB)		+= dbg_io.o
 obj-$(CONFIG_PCI)		+= pci-irq.o pci.o
 obj-$(CONFIG_SMP)          	+= smp.o
 obj-$(CONFIG_HYPERTRANSPORT)	+= ht-irq.o ht.o
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/pmc-sierra/yosemite/dbg_io.c linux-2.4.29-pre3/arch/mips/pmc-sierra/yosemite/dbg_io.c
--- linux-2.4.28/arch/mips/pmc-sierra/yosemite/dbg_io.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/pmc-sierra/yosemite/dbg_io.c	2004-12-22 16:06:42.331862520 +0000
@@ -0,0 +1,184 @@
+/*
+ * Copyright 2003 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Support for KGDB for the Yosemite board. We make use of single serial
+ * port to be used for KGDB as well as console. The second serial port
+ * seems to be having a problem. Single IRQ is allocated for both the 
+ * ports. Hence, the interrupt routing code needs to figure out whether
+ * the interrupt came from channel A or B.
+ */
+
+#include <linux/config.h>
+
+#if defined(CONFIG_KGDB)
+#include <asm/serial.h>
+
+/*
+ * Baud rate, Parity, Data and Stop bit settings for the 
+ * serial port on the Yosemite. Note that the Early printk
+ * patch has been added. So, we should be all set to go
+ */
+#define	YOSEMITE_BAUD_2400	2400
+#define	YOSEMITE_BAUD_4800	4800
+#define	YOSEMITE_BAUD_9600	9600
+#define	YOSEMITE_BAUD_19200	19200
+#define	YOSEMITE_BAUD_38400	38400
+#define	YOSEMITE_BAUD_57600	57600
+#define	YOSEMITE_BAUD_115200	115200
+
+#define	YOSEMITE_PARITY_NONE	0
+#define	YOSEMITE_PARITY_ODD	0x08
+#define	YOSEMITE_PARITY_EVEN	0x18
+#define	YOSEMITE_PARITY_MARK	0x28
+#define	YOSEMITE_PARITY_SPACE	0x38
+
+#define	YOSEMITE_DATA_5BIT	0x0
+#define	YOSEMITE_DATA_6BIT	0x1
+#define	YOSEMITE_DATA_7BIT	0x2
+#define	YOSEMITE_DATA_8BIT	0x3
+
+#define	YOSEMITE_STOP_1BIT	0x0
+#define	YOSEMITE_STOP_2BIT	0x4
+
+/* This is crucial */
+#define	SERIAL_REG_OFS		0x1
+
+#define	SERIAL_RCV_BUFFER	0x0
+#define	SERIAL_TRANS_HOLD	0x0
+#define	SERIAL_SEND_BUFFER	0x0
+#define	SERIAL_INTR_ENABLE	(1 * SERIAL_REG_OFS)
+#define	SERIAL_INTR_ID		(2 * SERIAL_REG_OFS)
+#define	SERIAL_DATA_FORMAT	(3 * SERIAL_REG_OFS)
+#define	SERIAL_LINE_CONTROL	(3 * SERIAL_REG_OFS)
+#define	SERIAL_MODEM_CONTROL	(4 * SERIAL_REG_OFS)
+#define	SERIAL_RS232_OUTPUT	(4 * SERIAL_REG_OFS)
+#define	SERIAL_LINE_STATUS	(5 * SERIAL_REG_OFS)
+#define	SERIAL_MODEM_STATUS	(6 * SERIAL_REG_OFS)
+#define	SERIAL_RS232_INPUT	(6 * SERIAL_REG_OFS)
+#define	SERIAL_SCRATCH_PAD	(7 * SERIAL_REG_OFS)
+
+#define	SERIAL_DIVISOR_LSB	(0 * SERIAL_REG_OFS)
+#define	SERIAL_DIVISOR_MSB	(1 * SERIAL_REG_OFS)
+
+/*
+ * Functions to READ and WRITE to serial port 0
+ */
+#define	SERIAL_READ(ofs)		(*((volatile unsigned char*)	\
+					(TITAN_SERIAL_BASE + ofs)))
+
+#define	SERIAL_WRITE(ofs, val)		((*((volatile unsigned char*)	\
+					(TITAN_SERIAL_BASE + ofs))) = val)
+
+/*
+ * Functions to READ and WRITE to serial port 1
+ */
+#define	SERIAL_READ_1(ofs)		(*((volatile unsigned char*)	\
+					(TITAN_SERIAL_BASE_1 + ofs)
+
+#define	SERIAL_WRITE_1(ofs, val)	((*((volatile unsigned char*)	\
+					(TITAN_SERIAL_BASE_1 + ofs))) = val)
+
+/*
+ * Second serial port initialization
+ */
+void init_second_port(void)
+{
+	/* Disable Interrupts */
+	SERIAL_WRITE_1(SERIAL_LINE_CONTROL, 0x0);
+	SERIAL_WRITE_1(SERIAL_INTR_ENABLE, 0x0);
+
+	{
+		unsigned int divisor;
+
+		SERIAL_WRITE_1(SERIAL_LINE_CONTROL, 0x80);
+		divisor = TITAN_SERIAL_BASE_BAUD / YOSEMITE_BAUD_115200;
+		SERIAL_WRITE_1(SERIAL_DIVISOR_LSB, divisor & 0xff);
+
+		SERIAL_WRITE_1(SERIAL_DIVISOR_MSB, (divisor & 0xff00) >> 8);
+		SERIAL_WRITE_1(SERIAL_LINE_CONTROL, 0x0);
+	}
+
+	SERIAL_WRITE_1(SERIAL_DATA_FORMAT, YOSEMITE_DATA_8BIT | 
+					   YOSEMITE_PARITY_NONE | 
+					   YOSEMITE_STOP_1BIT);
+
+	/* Enable Interrupts */
+	SERIAL_WRITE_1(SERIAL_INTR_ENABLE, 0xf);
+}
+
+/* Initialize the serial port for KGDB debugging */
+void debugInit(unsigned int baud, unsigned char data, unsigned char parity, 
+		unsigned char stop)
+{
+	/* Disable Interrupts */
+	SERIAL_WRITE(SERIAL_LINE_CONTROL, 0x0);
+	SERIAL_WRITE(SERIAL_INTR_ENABLE, 0x0);
+
+	{
+		unsigned int divisor;
+
+		SERIAL_WRITE(SERIAL_LINE_CONTROL, 0x80);
+
+		divisor = TITAN_SERIAL_BASE_BAUD / baud;
+		SERIAL_WRITE(SERIAL_DIVISOR_LSB, divisor & 0xff);
+
+		SERIAL_WRITE(SERIAL_DIVISOR_MSB, (divisor & 0xff00) >> 8);
+		SERIAL_WRITE(SERIAL_LINE_CONTROL, 0x0);
+	}
+
+	SERIAL_WRITE(SERIAL_DATA_FORMAT, data | parity | stop);
+}
+
+static int remoteDebugInitialized = 0;
+
+unsigned char getDebugChar(void)
+{
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(YOSEMITE_BAUD_115200,
+			  YOSEMITE_DATA_8BIT,
+			  YOSEMITE_PARITY_NONE, YOSEMITE_STOP_1BIT);
+	}
+
+	while ((SERIAL_READ(SERIAL_LINE_STATUS) & 0x1) == 0);
+	return SERIAL_READ(SERIAL_RCV_BUFFER);
+}
+
+int putDebugChar(unsigned char byte)
+{
+	if (!remoteDebugInitialized) {
+		remoteDebugInitialized = 1;
+		debugInit(YOSEMITE_BAUD_115200,
+			  YOSEMITE_DATA_8BIT,
+			  YOSEMITE_PARITY_NONE, YOSEMITE_STOP_1BIT);
+	}
+
+	while((SERIAL_READ(SERIAL_LINE_STATUS) & 0x20) == 0);
+	SERIAL_WRITE(SERIAL_SEND_BUFFER, byte);
+
+	return 1;
+}
+#endif
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/pmc-sierra/yosemite/ht-irq.c linux-2.4.29-pre3/arch/mips/pmc-sierra/yosemite/ht-irq.c
--- linux-2.4.28/arch/mips/pmc-sierra/yosemite/ht-irq.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/pmc-sierra/yosemite/ht-irq.c	2004-12-22 16:05:32.172528360 +0000
@@ -23,30 +23,194 @@
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+/*
+ * Currently there is support for:
+ *  Alliance Sipackets HT-PCI bridge
+ *  PLX HT-PCI bridge
+ *  Altera Hypertransport device
+ */
+
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
+#include <linux/version.h>
 #include <linux/init.h>
+#include <linux/pci_ids.h>
 #include <asm/pci.h>
 
+/* PLX Specific Defines */
+#ifdef CONFIG_PLX_HT_BRIDGE
+
+#define AMD_VENDOR_ID           0x1022
+#define AMD_DEVICE_ID           0x7450
+#define AMD_IOAPIC_ID           0x7451
+
+/* RDR Registers and Index */
+#define AMD_RDR_INDEX           0xb8
+#define AMD_RDR_VALUE           0xbc
+
+/* AMD RDR Index for INTX# */
+#define AMD_RDR_INTA            0x80100008
+#define AMD_RDR_INTB            0x80120008
+#define AMD_RDR_INTC            0x80140008
+#define AMD_RDR_INTD            0x80160008
+
+#endif
+
 /*
  * HT Bus fixup for the Titan
- * XXX IRQ values need to change based on the board layout
  */
 void __init titan_ht_pcibios_fixup_bus(struct pci_bus *bus)
 {
         struct pci_bus *current_bus = bus;
         struct pci_dev *devices;
         struct list_head *devices_link;
+	unsigned long cmd;
 
 	list_for_each(devices_link, &(current_bus->devices)) {
                 devices = pci_dev_b(devices_link);
                 if (devices == NULL)
                         continue;
-	}
 
+		/*
+		 * Set the device IRQ to 3. This coressponds to 
+		 * hardware interrupt line 0 and processor 
+		 * interrupt line 0
+		 */
+		devices->irq = 3;
+	}
 	/*
-	 * PLX and SPKT related changes go here
-	 */
+         * Turn on IO SPACE, MEM SPACE and BUS MASTER among
+         * other things
+         */
+
+	if (devices->vendor == PCI_VENDOR_ID_SIPACKETS) {
+
+		bus->ops->read_word(devices, PCI_COMMAND, &cmd);
+	        cmd |= 0x17;
+        	bus->ops->write_word(devices, PCI_COMMAND, cmd); 
+
+#ifdef CONFIG_SPKT_HT_BRIDGE
+		/*
+        	 * Configure the Block #0, #1, #2 and #3 
+		 * for interrupt routing
+        	 */
+		printk(KERN_INFO "Fixing SiPKT HT-PCI IOAPIC \n");
+
+#if 0 
+		/* Interrupt Routing Diagnostics */
+		bus->ops->write_byte(devices, 0xc2, 0x48); 
+#endif
+
+		/* 
+		 * The following are the config options:
+		 * Polarity is active low
+		 * Destination mode is logical
+		 * Destination processor is core 0
+		 * Message type is Fixed
+		 * Interrupt Vector configured to PIRQ 0
+		 */
+		bus->ops->write_dword(devices, 0xa0, 0xc0c1c0c0);
+		bus->ops->write_dword(devices, 0xa4, 0xc0c3c0c2);
+		bus->ops->write_dword(devices, 0xa8, 0xc0c1c0c0);
+		bus->ops->write_dword(devices, 0xac, 0xc0c3c0c2);
+		bus->ops->write_dword(devices, 0xb0, 0xc0c1c0c0);
+		bus->ops->write_dword(devices, 0xb4, 0xc0c3c0c2);
+		bus->ops->write_dword(devices, 0xb8, 0xc0c1c0c0);
+		bus->ops->write_dword(devices, 0xbc, 0xc0c3c0c2);
+
+		bus->ops->write_byte(devices, 0xc3, 0x47);
+		bus->ops->write_byte(devices, 0xc4, 0x47);
+		bus->ops->write_byte(devices, 0xc5, 0x47);
+		bus->ops->write_byte(devices, 0xc6, 0x47);
 
+		printk(KERN_ERR "Done configuring interrupts \n");
+
+#ifdef CONFIG_HT_LEVEL_TRIGGER
+		/*
+		 * Support for Level Triggered mode 
+		 */
+		bus->ops->write_dword(devices, 0xa0, 0xc0c5c0c4);
+		bus->ops->write_dword(devices, 0xa4, 0xc0c7c0c6);
+		bus->ops->write_dword(devices, 0xa8, 0xc0c5c0c4);
+		bus->ops->write_dword(devices, 0xaC, 0xc0c7c0c6);
+#endif
+		/* Set the cacheline size to 8 */
+		bus->ops->write_byte(devices, 0x0c, 0x08); 
+
+		/* Set the Prefetch related configuration */
+		bus->ops->write_dword(devices, 0x60, 0x0f3f0cff); 
+		bus->ops->read_dword(devices, 0x60, &cmd);
+
+		printk(KERN_ERR "Done configuring the Read Prefetch \n");
+#endif
+	
+#ifdef CONFIG_PLX_HT_BRIDGE
+		/*
+	         * For the HT-PCIX bridge, we need to make changes to
+        	 * the IO space limits. Note that this is valid only for
+	         * the AMD 7450 PLX bridge. Hence we need to compare with
+        	 * that
+	         */
+		if (devices->vendor == AMD_VENDOR_ID &&
+			devices->device == AMD_DEVICE_ID) {
+			printk(KERN_INFO "AMD HT-PCIX bridge found  ");
+
+			/*
+			 * These are the RDR (Redirection Registers) for the 
+			 * AMD 8131 IOAPIC
+			 */
+	
+			/* INTA# */
+			bus->ops->write_dword(devices, AMD_RDR_INDEX, AMD_RDR_INTA);
+			bus->ops->write_dword(devices, AMD_RDR_VALUE, 0xf8200140);
+
+			/* INTB# */
+			bus->ops->write_dword(devices, AMD_RDR_INDEX, AMD_RDR_INTB);
+			bus->ops->write_dword(devices, AMD_RDR_VALUE, 0xf8200140);
+
+			/* INTC# */
+			bus->ops->write_dword(devices, AMD_RDR_INDEX, AMD_RDR_INTC);
+			bus->ops->write_dword(devices, AMD_RDR_VALUE, 0xf8200140);
+
+			/* INTD# */
+			bus->ops->write_dword(devices, AMD_RDR_INDEX, AMD_RDR_INTD);
+			bus->ops->write_dword(devices, AMD_RDR_VALUE, 0xf8200140);
+
+			/* Enable the Prefetching, MRM and MRL */
+			bus->ops->read_dword(devices, 0x4c, &val);
+			val |= 0x00001dc0;
+			bus->ops->write_dword(devices, 0x4c, val);
+		}
+
+		if (devices->vendor == AMD_VENDOR_ID &&
+			devices->device == AMD_IOAPIC_ID) {
+			printk("AMD 8131 IO APIC Fixup \n");
+
+			/* Turn the IOAPIC ON */
+			bus->ops->write_dword(devices, 0x44, 0x00000003);
+		}
+#endif /* CONFIG_PLX_HT_BRIDGE */
+#ifdef CONFIG_ALTERA_HT_BRIDGE
+		if ( (devices->vendor == PCI_VENDOR_ID_ALTERA) &&
+			(devices->device == PCI_DEVICE_ID_ALTERA_HT_BRIDGE)) {
+			printk(KERN_INFO "Found an Altera HT device, fixing up \n");
+		}
+
+		/* Check if the Link Initialization completed successfully */
+		bus->ops->read_dword(devices, 0x44, &val);
+		if (!(val & 0x20))
+			printk(KERN_ERR "Link Initialization Error !! \n");
+#endif /* CONFIG_ALTERA_HT_BRIDGE */
+
+		/* enable master */
+		if (((current_bus->number != 0) && (current_bus->number != 1))
+				|| (PCI_SLOT(devices->devfn) != 0)) {
+			bus->ops->read_word(devices, PCI_COMMAND, &cmd);
+			cmd |= PCI_COMMAND_MASTER;
+			bus->ops->write_word(devices, PCI_COMMAND, cmd);
+		}
+
+	}
 }
+
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/pmc-sierra/yosemite/ht.c linux-2.4.29-pre3/arch/mips/pmc-sierra/yosemite/ht.c
--- linux-2.4.28/arch/mips/pmc-sierra/yosemite/ht.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/pmc-sierra/yosemite/ht.c	2004-12-22 16:07:09.903670968 +0000
@@ -28,6 +28,8 @@
 #include <linux/pci.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
+#include <linux/version.h>
+#include <linux/delay.h>
 #include <asm/pci.h>
 #include <asm/io.h>
 
@@ -36,7 +38,6 @@
 
 #ifdef CONFIG_HYPERTRANSPORT
 
-
 /*
  * This function check if the Hypertransport Link Initialization completed. If
  * it did, then proceed further with scanning bus #2
@@ -47,7 +48,6 @@ static __inline__ int check_titan_htlink
 
         val = *(volatile u_int32_t *)(RM9000x2_HTLINK_REG);
         if (val & 0x00000020)
-                /* HT Link Initialization completed */
                 return 1;
         else
                 return 0;
@@ -57,25 +57,41 @@ static int titan_ht_config_read_dword(st
                                              int offset, u32* val)
 {
         int dev, bus, func;
-        uint32_t address_reg, data_reg;
-        uint32_t address;
+        volatile uint32_t address;
+	unsigned long reg_data;
 
         bus = device->bus->number;
         dev = PCI_SLOT(device->devfn);
         func = PCI_FUNC(device->devfn);
 
-	/* XXX Need to change the Bus # */
-        if (bus > 2)
-                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
-                                                        0x80000000 | 0x1;
-        else
-                address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
-
-        address_reg = RM9000x2_OCD_HTCFGA;
-        data_reg =  RM9000x2_OCD_HTCFGD;
+	if (bus != 0)
+		address = (bus << 16) | (dev << 11) | (func << 8) | 
+				(offset & 0xfc) | 0x80000000 | 0x1;
+	else
+		address = (bus << 16) | (dev << 11) | (func << 8) |
+				(offset & 0xfc) | 0x80000000;
+	
+	/*
+	 * RM9000 HT Errata: Issue back to back HT config
+	 * transcations. Issue a BIU sync before and 
+	 * after the HT cycle
+	 */
+
+	reg_data = *(volatile u_int32_t *)(0xfb0000f0);
+	reg_data |= 0x2;
+	*(volatile u_int32_t *)(0xfb0000f0) = reg_data;
+
+	udelay(30);
+
+	*(volatile u_int32_t *)(0xfb0006f8) = address;
+	*(val) = *(volatile u_int32_t *)(0xfb0006fc);
+
+	udelay(30);
+
+	reg_data = *(volatile u_int32_t *)(0xfb0000f0);
+        reg_data |= 0x2;
+        *(volatile u_int32_t *)(0xfb0000f0) = reg_data;
 
-        RM9K_WRITE(address_reg, address);
-        RM9K_READ(data_reg, val);
 
         return PCIBIOS_SUCCESSFUL;
 }
@@ -85,30 +101,25 @@ static int titan_ht_config_read_word(str
                                              int offset, u16* val)
 {
         int dev, bus, func;
-        uint32_t address_reg, data_reg;
-        uint32_t address;
+        volatile uint32_t address_reg, data_reg;
+        uint32_t address, *val1 = kmalloc(sizeof(uint32_t), GFP_KERNEL);
 
         bus = device->bus->number;
         dev = PCI_SLOT(device->devfn);
         func = PCI_FUNC(device->devfn);
 
-	/* XXX Need to change the Bus # */
-        if (bus > 2)
-                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
-                                                0x80000000 | 0x1;
-        else
-                address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
+	address =  (bus << 16) | (dev << 11) | (func << 8) | 
+			(offset & 0xfc) | 0x80000000;
 
         address_reg = RM9000x2_OCD_HTCFGA;
         data_reg =  RM9000x2_OCD_HTCFGD;
 
+	titan_ht_config_read_dword(device, offset, val1);
+
         if ((offset & 0x3) == 0)
-                offset = 0x2;
+		*val = (*val1 & 0x0000ffff);
         else
-                offset = 0x0;
-
-        RM9K_WRITE(address_reg, address);
-        RM9K_READ_16(data_reg + offset, val);
+		*val = (*val1 & 0xffff0000) >> 16;
 
         return PCIBIOS_SUCCESSFUL;
 }
@@ -131,99 +142,103 @@ static int titan_ht_config_read_byte(str
                                              int offset, u8* val)
 {
         int dev, bus, func;
-        uint32_t address_reg, data_reg;
-        uint32_t address;
-        int offset1;
+        volatile uint32_t address_reg, data_reg;
+        uint32_t address, *val1 = kmalloc(sizeof(uint32_t), GFP_KERNEL);
 
         bus = device->bus->number;
         dev = PCI_SLOT(device->devfn);
         func = PCI_FUNC(device->devfn);
 
-	/* XXX Need to change the Bus # */
-        if (bus > 2)
-                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
-                                                        0x80000000 | 0x1;
-        else
-                address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
+        address = (bus << 16) | (dev << 11) | (func << 8) | 
+			(offset & 0xfc) | 0x80000000;
 
         address_reg = RM9000x2_OCD_HTCFGA;
         data_reg =  RM9000x2_OCD_HTCFGD;
 
-        RM9K_WRITE(address_reg, address);
+	titan_ht_config_read_dword(device, offset, val1);
 
         if ((offset & 0x3) == 0) {
-                offset1 = 0x3;
+		*val = (*val1 & 0x000000ff);
         }
         if ((offset & 0x3) == 1) {
-                offset1 = 0x2;
+		*val = ((*val1 & 0x0000ff00) >> 8);
         }
         if ((offset & 0x3) == 2) {
-                offset1 = 0x1;
+		*val = ((*val1 & 0x00ff0000) >> 16);
         }
         if ((offset & 0x3) == 3) {
-                offset1 = 0x0;
-        }
-        RM9K_READ_8(data_reg + offset1, val);
+		*val = ((*val1 & 0xff000000) >> 24);
+        } 
 
         return PCIBIOS_SUCCESSFUL;
 }
 
 
 static int titan_ht_config_write_dword(struct pci_dev *device,
-                                             int offset, u8 val)
+                                             int offset, u32 val)
 {
         int dev, bus, func;
-        uint32_t address_reg, data_reg;
-        uint32_t address;
+        volatile uint32_t address;
+	unsigned long reg_data;
 
         bus = device->bus->number;
         dev = PCI_SLOT(device->devfn);
         func = PCI_FUNC(device->devfn);
 
-	/* XXX Need to change the Bus # */
-        if (bus > 2)
-                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
-                                                        0x80000000 | 0x1;
-        else
-              address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
-
-        address_reg = RM9000x2_OCD_HTCFGA;
-        data_reg =  RM9000x2_OCD_HTCFGD;
-
-        RM9K_WRITE(address_reg, address);
-        RM9K_WRITE(data_reg, val);
+	if (bus != 0)        
+		address = (bus << 16) | (dev << 11) | (func << 8) | 
+				(offset & 0xfc) | 0x80000000 | 0x1;
+	else
+		address = (bus << 16) | (dev << 11) | (func << 8) |
+				(offset & 0xfc) | 0x80000000;
+
+	reg_data = *(volatile u_int32_t *)(0xfb0000f0);
+        reg_data |= 0x2;
+        *(volatile u_int32_t *)(0xfb0000f0) = reg_data;
+	
+	udelay(30);
+
+	*(volatile u_int32_t *)(0xfb0006f8) = address;
+        *(volatile u_int32_t *)(0xfb0006fc) = val;
+
+	udelay(30);
+
+	reg_data = *(volatile u_int32_t *)(0xfb0000f0);
+        reg_data |= 0x2;
+        *(volatile u_int32_t *)(0xfb0000f0) = reg_data;
 
         return PCIBIOS_SUCCESSFUL;
 }
 
 static int titan_ht_config_write_word(struct pci_dev *device,
-                                             int offset, u8 val)
+                                             int offset, u16 val)
 {
         int dev, bus, func;
-        uint32_t address_reg, data_reg;
-        uint32_t address;
+        volatile uint32_t address_reg, data_reg;
+        uint32_t address, val1, val2;
 
         bus = device->bus->number;
         dev = PCI_SLOT(device->devfn);
         func = PCI_FUNC(device->devfn);
 
-	/* XXX Need to change the Bus # */
-        if (bus > 2)
-                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
-                                0x80000000 | 0x1;
-        else
-                address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
+        address = (bus << 16) | (dev << 11) | (func << 8) | 
+			(offset & 0xfc) | 0x80000000;
 
         address_reg = RM9000x2_OCD_HTCFGA;
         data_reg =  RM9000x2_OCD_HTCFGD;
 
-        if ((offset & 0x3) == 0)
-                offset = 0x2;
-        else
-                offset = 0x0;
+	titan_ht_config_read_dword(device, offset, &val2);
+
+        if ((offset & 0x3) == 0) {
+		val2 = ( (val2 & ~(0x0000ffff)) | val);
+	}
+	else {
+		val1 = val;
+		val1 = (val1 << 16);
+		val2 = ( (val2 & ~(0xffff0000)) | val1);
+	}
 
-        RM9K_WRITE(address_reg, address);
-        RM9K_WRITE_16(data_reg + offset, val);
+	titan_ht_config_write_dword(device, offset, val2);
 
         return PCIBIOS_SUCCESSFUL;
 }
@@ -232,44 +247,49 @@ static int titan_ht_config_write_byte(st
                                              int offset, u8 val)
 {
         int dev, bus, func;
-        uint32_t address_reg, data_reg;
-        uint32_t address;
+        volatile uint32_t address_reg, data_reg;
+        uint32_t address, val1, val2;
         int offset1;
 
         bus = device->bus->number;
         dev = PCI_SLOT(device->devfn);
         func = PCI_FUNC(device->devfn);
 
-	/* XXX Need to change the Bus # */
-        if (bus > 2)
-                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
-                                0x80000000 | 0x1;
-        else
-                address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
+        address = (bus << 16) | (dev << 11) | (func << 8) | 
+			(offset & 0xfc) | 0x80000000;
 
         address_reg = RM9000x2_OCD_HTCFGA;
         data_reg =  RM9000x2_OCD_HTCFGD;
 
-        RM9K_WRITE(address_reg, address);
+	titan_ht_config_read_dword(device, offset, &val2);
 
         if ((offset & 0x3) == 0) {
-             offset1 = 0x3;
+		val1 = val;
+		val2 = ( (val2 & ~(0x000000ff)) | val1);
         }
         if ((offset & 0x3) == 1) {
-             offset1 = 0x2;
+		val1 = val;
+		val1 = val1 << 8;
+		val2 = ( (val2 & ~(0x0000ff00)) | val1);
         }
         if ((offset & 0x3) == 2) {
-             offset1 = 0x1;
+		val1 = val;
+		val1 = val1 << 16;
+		val2 = ( (val2 & ~(0x00ff0000)) | val1);
         }
         if ((offset & 0x3) == 3) {
-            offset1 = 0x0;
+		val1 = val;
+		val1 = val1 << 24;
+		val2 = ( (val2 & ~(0xff000000)) | val1);
         }
 
-        RM9K_WRITE_8(data_reg + offset1, val);
+	titan_ht_config_write_dword(device, offset, val2);
         return PCIBIOS_SUCCESSFUL;
 }
 
-
+/*
+ * Bus mastering capabilities for the HT device
+ */
 static void titan_pcibios_set_master(struct pci_dev *dev)
 {
         u16 cmd;
@@ -289,6 +309,7 @@ int pcibios_enable_resources(struct pci_
 {
         u16 cmd, old_cmd;
         u8 tmp1;
+	u32 reg_data;
         int idx;
         struct resource *r;
         int bus = dev->bus->number;
@@ -300,10 +321,11 @@ int pcibios_enable_resources(struct pci_
         for (idx = 0; idx < 6; idx++) {
                 r = &dev->resource[idx];
                 if (!r->start && r->end) {
+			printk("%x    %x \n", r->start,  r->end);
                         printk(KERN_ERR
                                "PCI: Device %s not available because of "
                                "resource collisions\n", dev->slot_name);
-                        return -EINVAL;
+			return -EINVAL;
                 }
                 if (r->flags & IORESOURCE_IO)
                         cmd |= PCI_COMMAND_IO;
@@ -346,8 +368,6 @@ int pcibios_enable_device(struct pci_dev
         return pcibios_enable_resources(dev);
 }
 
-
-
 void pcibios_update_resource(struct pci_dev *dev, struct resource *root,
                              struct resource *res, int resource)
 {
@@ -404,6 +424,9 @@ void pcibios_align_resource(void *data, 
         }
 }
 
+/*
+ * PCI structure
+ */
 struct pci_ops titan_pci_ops = {
         titan_ht_config_read_byte,
         titan_ht_config_read_word,
@@ -425,17 +448,20 @@ void __init pcibios_fixup_bus(struct pci
 
 void __init pcibios_init(void)
 {
+	/*
+	 * IO space accesses for the device
+	 */
+	set_io_port_base(KSEG1);
+
+	/* 
+	 * IO and MEM space values
+	 */
+	ioport_resource.start = 0xe0000000;
+        ioport_resource.end   = 0xe0000000 + 0x01000000 - 1;
+        iomem_resource.start  = 0xd0000000;
+        iomem_resource.end    = 0xd0000000 + 0x0f000000 - 1;
 
-        /* Reset PCI I/O and PCI MEM values */
-	/* XXX Need to add the proper values here */
-        ioport_resource.start = 0xe0000000;
-        ioport_resource.end   = 0xe0000000 + 0x20000000 - 1;
-        iomem_resource.start  = 0xc0000000;
-        iomem_resource.end    = 0xc0000000 + 0x20000000 - 1;
-
-	/* XXX Need to add bus values */
-        pci_scan_bus(2, &titan_pci_ops, NULL);
-        pci_scan_bus(3, &titan_pci_ops, NULL);
+        pci_scan_bus(0, &titan_pci_ops, NULL);
 }
 
 /*
@@ -444,15 +470,13 @@ void __init pcibios_init(void)
 char *pcibios_setup(char *str)
 {
         printk(KERN_INFO "rr: pcibios_setup\n");
-        /* Nothing to do for now.  */
 
         return str;
 }
 
 unsigned __init int pcibios_assign_all_busses(void)
 {
-        /* We want to use the PCI bus detection done by PMON */
-        return 0;
+        return 1;
 }
 
 #endif /* CONFIG_HYPERTRANSPORT */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/pmc-sierra/yosemite/irq-handler.S linux-2.4.29-pre3/arch/mips/pmc-sierra/yosemite/irq-handler.S
--- linux-2.4.28/arch/mips/pmc-sierra/yosemite/irq-handler.S	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/pmc-sierra/yosemite/irq-handler.S	2004-12-22 16:07:00.616082896 +0000
@@ -10,7 +10,6 @@
  * option) any later version.
  */
 
-#define __ASSEMBLY__
 #include <linux/config.h>
 #include <asm/asm.h>
 #include <asm/mipsregs.h>
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/pmc-sierra/yosemite/irq.c linux-2.4.29-pre3/arch/mips/pmc-sierra/yosemite/irq.c
--- linux-2.4.28/arch/mips/pmc-sierra/yosemite/irq.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/pmc-sierra/yosemite/irq.c	2004-12-22 16:05:31.749592656 +0000
@@ -87,7 +87,7 @@ static inline void modify_cp0_intmask(un
         set_mask = 0xff & set_mask_in;
         status = read_c0_status();
         status &= ~((clr_mask & 0xFF) << 8);
-        status |= (set_mask & 0xFF) << 8 | 0x0000FF00;
+        status |= (set_mask & 0xFF) << 8;
         write_c0_status(status);
 
         /* do the high 8 bits */
@@ -96,6 +96,7 @@ static inline void modify_cp0_intmask(un
         status = read_32bit_cp0_set1_register(CP0_S1_INTCONTROL);
         status &= ~((clr_mask & 0xFF) << 8);
         status |= (set_mask & 0xFF) << 8;
+	status |= (1 << 13);
         write_32bit_cp0_set1_register(CP0_S1_INTCONTROL, status);
 }
 
@@ -224,6 +225,17 @@ done:
 		do_IRQ(irq, regs);	
 }
 
+static struct irqaction unused_irq =
+	{ no_action, SA_INTERRUPT, 0, "unused", NULL, NULL };
+
+extern unsigned long exception_handlers[32];
+
+#ifdef CONFIG_KGDB
+extern void init_second_port(void);
+extern void breakpoint(void);
+extern void set_debug_traps(void);
+#endif
+
 /*
  * Initialize the next level interrupt handler
  */
@@ -237,11 +249,37 @@ void __init init_IRQ(void)
 	set_except_vector(0, titan_handle_int);
 	init_generic_irq();
 
-	for (i = 0; i < 13; i++) {
+	for (i = 0; i < 12; i++) {
                 irq_desc[i].status      = IRQ_DISABLED;
                 irq_desc[i].action      = 0;
                 irq_desc[i].depth       = 1;
                 irq_desc[i].handler     = &rm9000_hpcdma_irq_type;
         }
+
+#ifdef CONFIG_KGDB
+	/* At this point, initialize the second serial port */
+	init_second_port();
+	printk("Start kgdb ... \n");
+	set_debug_traps();
+	breakpoint();
+#endif
+
+#ifdef CONFIG_GDB_CONSOLE
+	register_gdb_console();
+#endif
 }
 
+#ifdef CONFIG_KGDB
+/* 
+ * The 16550 DUART has two ports, but is allocated one IRQ 
+ * for the serial console. Hence, a generic framework for
+ * serial IRQ routing in place. Currently, just calls the 
+ * do_IRQ fuction. But, going in the future, need to check
+ * DUART registers for channel A and B, then decide the 
+ * appropriate action
+ */
+asmlinkage void yosemite_kgdb_irq(int irq, struct pt_regs *regs)
+{
+	do_IRQ(irq, regs);
+}
+#endif
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/ramdisk/Makefile linux-2.4.29-pre3/arch/mips/ramdisk/Makefile
--- linux-2.4.28/arch/mips/ramdisk/Makefile	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/ramdisk/Makefile	2004-12-22 16:07:33.036154296 +0000
@@ -10,6 +10,6 @@ O_FORMAT = $(shell $(OBJDUMP) -i | head 
 img = $(CONFIG_EMBEDDED_RAMDISK_IMAGE)
 ramdisk.o: $(subst ",,$(img)) ld.script
 	echo "O_FORMAT:  " $(O_FORMAT)
-	$(LD) -T ld.script -b binary --oformat $(O_FORMAT) -o $@ $(img)
+	$(LD) $(LDFLAGS) -T ld.script -b binary --oformat $(O_FORMAT) -o $@ $(img)
 
 include $(TOPDIR)/Rules.make
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/sgi-ip22/ip22-setup.c linux-2.4.29-pre3/arch/mips/sgi-ip22/ip22-setup.c
--- linux-2.4.28/arch/mips/sgi-ip22/ip22-setup.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/sgi-ip22/ip22-setup.c	2004-12-22 16:07:09.612715200 +0000
@@ -139,8 +139,10 @@ void __init ip22_setup(void)
 	indy_sc_init();
 #endif
 
-	/* Set EISA IO port base for Indigo2 */
-	set_io_port_base(KSEG1ADDR(0x00080000));
+	/* Set EISA IO port base for Indigo2
+	 * ioremap cannot fail */
+	set_io_port_base((unsigned long)ioremap(0x00080000,
+						0x1fffffff - 0x00080000));
 
 	/* Nothing registered console before us, so simply use first entry */
 	c = &console_cmdline[0];
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/sgi-ip27/Makefile linux-2.4.29-pre3/arch/mips/sgi-ip27/Makefile
--- linux-2.4.28/arch/mips/sgi-ip27/Makefile	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/sgi-ip27/Makefile	2004-12-22 16:07:40.976947112 +0000
@@ -6,6 +6,8 @@ USE_STANDARD_AS_RULE := true
 
 O_TARGET = ip27.o
 
+export-objs := ip27-init.o ip27-memory.o
+
 obj-y	:= ip27-berr.o ip27-console.o ip27-irq.o ip27-init.o ip27-irq-glue.o \
 	   ip27-klconfig.o ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-pci.o \
 	   ip27-reset.o ip27-setup.o ip27-timer.o
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/sgi-ip27/ip27-init.c linux-2.4.29-pre3/arch/mips/sgi-ip27/ip27-init.c
--- linux-2.4.28/arch/mips/sgi-ip27/ip27-init.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/sgi-ip27/ip27-init.c	2004-12-22 16:07:42.318743128 +0000
@@ -13,6 +13,8 @@
 #include <linux/sched.h>
 #include <linux/mmzone.h>	/* for numnodes */
 #include <linux/mm.h>
+#include <linux/module.h>
+
 #include <asm/cpu.h>
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
@@ -55,11 +57,15 @@ static atomic_t numstarted = ATOMIC_INIT
 static int router_distance;
 nasid_t master_nasid = INVALID_NASID;
 
+EXPORT_SYMBOL(master_nasid);
+
 cnodeid_t	nasid_to_compact_node[MAX_NASIDS];
 nasid_t		compact_to_nasid_node[MAX_COMPACT_NODES];
 cnodeid_t	cpuid_to_compact_node[MAXCPUS];
 char		node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES];
 
+EXPORT_SYMBOL(nasid_to_compact_node);
+
 hubreg_t get_region(cnodeid_t cnode)
 {
 	if (fine_mode)
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/sgi-ip27/ip27-memory.c linux-2.4.29-pre3/arch/mips/sgi-ip27/ip27-memory.c
--- linux-2.4.28/arch/mips/sgi-ip27/ip27-memory.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/sgi-ip27/ip27-memory.c	2004-12-22 16:06:05.477465240 +0000
@@ -15,6 +15,7 @@
 #include <linux/mm.h>
 #include <linux/bootmem.h>
 #include <linux/swap.h>
+#include <linux/module.h>
 
 #include <asm/page.h>
 #include <asm/bootinfo.h>
@@ -40,6 +41,8 @@ static pfn_t numpages;
 plat_pg_data_t *plat_node_data[MAX_COMPACT_NODES];
 bootmem_data_t plat_node_bdata[MAX_COMPACT_NODES];
 
+EXPORT_SYMBOL(plat_node_data);
+
 int numa_debug(void)
 {
 	printk("NUMA debug\n");
@@ -47,6 +50,8 @@ int numa_debug(void)
 	return(0);
 }
 
+EXPORT_SYMBOL(numa_debug);
+
 /*
  * Return the number of pages of memory provided by the given slot
  * on the specified node.
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/sgi-ip27/ip27-timer.c linux-2.4.29-pre3/arch/mips/sgi-ip27/ip27-timer.c
--- linux-2.4.28/arch/mips/sgi-ip27/ip27-timer.c	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/sgi-ip27/ip27-timer.c	2004-12-22 16:06:25.168471752 +0000
@@ -51,9 +51,8 @@ static int set_rtc_mmss(unsigned long no
 	struct m48t35_rtc *rtc;
 	nasid_t nid;
 
-	nid = get_nasid();
-	rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base +
-							IOC3_BYTEBUS_DEV0);
+	rtc = (struct m48t35_rtc *)
+	(KL_CONFIG_CH_CONS_INFO(master_nasid)->memory_base + IOC3_BYTEBUS_DEV0);
 
 	spin_lock(&rtc_lock);
 	rtc->control |= M48T35_RTC_READ;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/sibyte/cfe/setup.c linux-2.4.29-pre3/arch/mips/sibyte/cfe/setup.c
--- linux-2.4.28/arch/mips/sibyte/cfe/setup.c	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/sibyte/cfe/setup.c	2004-12-22 16:06:37.872540440 +0000
@@ -19,6 +19,7 @@
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/linkage.h>
 #include <linux/mm.h>
 #include <linux/blk.h>
 #include <linux/bootmem.h>
@@ -64,33 +65,43 @@ extern unsigned char __rd_start;
 extern unsigned char __rd_end;
 #endif
 
-#ifdef CONFIG_SMP
-static int reboot_smp = 0;
-#endif
-
 #ifdef CONFIG_KGDB
 extern int kgdb_port;
 #endif
 
-static void cfe_linux_exit(void)
+static void ATTRIB_NORET cfe_linux_exit(void *arg)
 {
-#ifdef CONFIG_SMP
+	int warm = *(int *)arg;
+
 	if (smp_processor_id()) {
-		if (reboot_smp) {
-			/* Don't repeat the process from another CPU */
-			for (;;);
-		} else {
+		static int reboot_smp;
+
+		/* Don't repeat the process from another CPU */
+		if (!reboot_smp) {
 			/* Get CPU 0 to do the cfe_exit */
 			reboot_smp = 1;
-			smp_call_function((void *)_machine_restart, NULL, 1, 0);
-			for (;;);
+			smp_call_function(cfe_linux_exit, arg, 1, 0);
 		}
+	} else {
+		printk("Passing control back to CFE...\n");
+		cfe_exit(warm, 0);
+		printk("cfe_exit returned??\n");
 	}
-#endif
-	printk("passing control back to CFE\n");
-	cfe_exit(1, 0);
-	printk("cfe_exit returned??\n");
-	while(1);
+	while (1);
+}
+
+static void ATTRIB_NORET cfe_linux_restart(char *command)
+{
+	static const int zero;
+
+	cfe_linux_exit((void *)&zero);
+}
+
+static void ATTRIB_NORET cfe_linux_halt(void)
+{
+	static const int one = 1;
+
+	cfe_linux_exit((void *)&one);
 }
 
 static __init void prom_meminit(void)
@@ -250,9 +261,9 @@ __init int prom_init(int argc, char **ar
 	char *arg;
 #endif
 
-	_machine_restart   = (void (*)(char *))cfe_linux_exit;
-	_machine_halt      = cfe_linux_exit;
-	_machine_power_off = cfe_linux_exit;
+	_machine_restart   = cfe_linux_restart;
+	_machine_halt      = cfe_linux_halt;
+	_machine_power_off = cfe_linux_halt;
 
 	/*
 	 * Check if a loader was used; if NOT, the 4 arguments are
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/sibyte/cfe/smp.c linux-2.4.29-pre3/arch/mips/sibyte/cfe/smp.c
--- linux-2.4.28/arch/mips/sibyte/cfe/smp.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/sibyte/cfe/smp.c	2004-12-22 16:07:52.230236352 +0000
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation
+ * Copyright (C) 2004  Maciej W. Rozycki
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -26,7 +27,7 @@
 
 /* Boot all other cpus in the system, initialize them, and
    bring them into the boot fn */
-void prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp)
+int prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp)
 {
 	int retval;
 	
@@ -34,6 +35,8 @@ void prom_boot_secondary(int cpu, unsign
 	if (retval != 0) {
 		printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval);
 	}
+
+	return retval;
 }
 
 void prom_init_secondary(void)
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/sibyte/sb1250/irq_handler.S linux-2.4.29-pre3/arch/mips/sibyte/sb1250/irq_handler.S
--- linux-2.4.28/arch/mips/sibyte/sb1250/irq_handler.S	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/sibyte/sb1250/irq_handler.S	2004-12-22 16:07:22.445764280 +0000
@@ -125,7 +125,7 @@
 	 * check the 1250 interrupt registers to figure out what to do
 	 * Need to detect which CPU we're on, now that smp_affinity is supported.
 	 */
-	la	v0, KSEG1 + A_IMR_CPU0_BASE
+	PTR_LA	v0, KSEG1 + A_IMR_CPU0_BASE
 #ifdef CONFIG_SMP
 	lw	t1, TASK_PROCESSOR($28)
 	sll	t1, IMR_REGISTER_SPACING_SHIFT
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/sibyte/sb1250/smp.c linux-2.4.29-pre3/arch/mips/sibyte/sb1250/smp.c
--- linux-2.4.28/arch/mips/sibyte/sb1250/smp.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/sibyte/sb1250/smp.c	2004-12-22 16:06:36.716716152 +0000
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2001 Broadcom Corporation
+ * Copyright (C) 2004  Maciej W. Rozycki
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -138,10 +139,10 @@ void __init smp_boot_cpus(void)
 	 * This loop attempts to compensate for "holes" in the CPU
 	 * numbering.  It's overkill, but general.
 	 */
-	for (i = 1; i < smp_num_cpus; ) {
+	for (i = 1; i < smp_num_cpus && cur_cpu < NR_CPUS; i++) {
 		struct task_struct *p;
 		struct pt_regs regs;
-		printk("Starting CPU %d... ", i);
+		printk("Starting CPU %d...\n", i);
 
 		/* Spawn a new process normally.  Grab a pointer to
 		   its task struct so we can mess with it */
@@ -158,15 +159,20 @@ void __init smp_boot_cpus(void)
 		unhash_process(p);
 
 		do {
+			int status;
+
 			/* Iterate until we find a CPU that comes up */
 			cur_cpu++;
-			prom_boot_secondary(cur_cpu,
-					    (unsigned long)p + KERNEL_STACK_SIZE - 32,
-					    (unsigned long)p);
+			status = prom_boot_secondary(cur_cpu,
+						    (unsigned long)p +
+						    KERNEL_STACK_SIZE - 32,
+						    (unsigned long)p);
+			if (status == 0) {
+				__cpu_number_map[cur_cpu] = i;
+				__cpu_logical_map[i] = cur_cpu;
+				break;
+			}
 		} while (cur_cpu < NR_CPUS);
-		__cpu_number_map[cur_cpu] = i;
-		__cpu_logical_map[i] = cur_cpu;
-		i++;
 	}
 
 	/* Wait for everyone to come up */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/sibyte/swarm/Makefile linux-2.4.29-pre3/arch/mips/sibyte/swarm/Makefile
--- linux-2.4.28/arch/mips/sibyte/swarm/Makefile	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/sibyte/swarm/Makefile	2004-12-22 16:05:32.256515592 +0000
@@ -1,13 +1,9 @@
 USE_STANDARD_AS_RULE := true
 
-all: sbswarm.a
+L_TARGET = sbswarm.a
 
-OBJS-y                   = setup.o cmdline.o rtc_xicor1241.o rtc_m41t81.o
+obj-y			+= setup.o cmdline.o rtc_xicor1241.o rtc_m41t81.o
 
-OBJS-$(CONFIG_KGDB) += dbg_io.o
-
-sbswarm.a: $(OBJS-y)
-	$(AR) rcs sbswarm.a $^
+obj-$(CONFIG_KGDB)	+= dbg_io.o
 
 include $(TOPDIR)/Rules.make
-
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/vr41xx/casio-e55/ide-e55.c linux-2.4.29-pre3/arch/mips/vr41xx/casio-e55/ide-e55.c
--- linux-2.4.28/arch/mips/vr41xx/casio-e55/ide-e55.c	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/vr41xx/casio-e55/ide-e55.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,99 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * IDE routines for typical pc-like standard configurations
- * for the CASIO CASSIOPEIA E-55/65.
- *
- * Copyright (C) 1998, 1999, 2001 by Ralf Baechle
- */
-/*
- * Changes:
- *  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>  Sun, 24 Feb 2002
- *  - Added CASIO CASSIOPEIA E-55/65 support.
- */
-#include <linux/sched.h>
-#include <linux/ide.h>
-#include <linux/ioport.h>
-#include <linux/hdreg.h>
-#include <asm/ptrace.h>
-#include <asm/hdreg.h>
-
-static int e55_ide_default_irq(ide_ioreg_t base)
-{
-	return 40;
-}
-
-static ide_ioreg_t e55_ide_default_io_base(int index)
-{
-	switch (index) {
-		case 0: return 0xc1f0;
-		case 1: return 0xc170;
-		case 2: return 0xc1e8;
-		case 3: return 0xc168;
-		case 4: return 0xc1e0;
-		case 5: return 0xc160;
-	}
-	return 0;
-}
-
-static void e55_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port,
-                                    ide_ioreg_t ctrl_port, int *irq)
-{
-	ide_ioreg_t reg = data_port;
-	int i;
-
-	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
-		hw->io_ports[i] = reg;
-		reg += 1;
-	}
-	if (ctrl_port) {
-		hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
-	} else {
-		hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206;
-	}
-	if (irq != NULL)
-		*irq = 0;
-	hw->io_ports[IDE_IRQ_OFFSET] = 0;
-}
-
-static int e55_ide_request_irq(unsigned int irq,
-                               void (*handler)(int,void *, struct pt_regs *),
-                               unsigned long flags, const char *device,
-                               void *dev_id)
-{
-	return request_irq(irq, handler, flags, device, dev_id);
-}			
-
-static void e55_ide_free_irq(unsigned int irq, void *dev_id)
-{
-	free_irq(irq, dev_id);
-}
-
-static int e55_ide_check_region(ide_ioreg_t from, unsigned int extent)
-{
-	return check_region(from, extent);
-}
-
-static void e55_ide_request_region(ide_ioreg_t from, unsigned int extent,
-                                   const char *name)
-{
-	request_region(from, extent, name);
-}
-
-static void e55_ide_release_region(ide_ioreg_t from, unsigned int extent)
-{
-	release_region(from, extent);
-}
-
-struct ide_ops e55_ide_ops = {
-	&e55_ide_default_irq,
-	&e55_ide_default_io_base,
-	&e55_ide_init_hwif_ports,
-	&e55_ide_request_irq,
-	&e55_ide_free_irq,
-	&e55_ide_check_region,
-	&e55_ide_request_region,
-	&e55_ide_release_region
-};
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/vr41xx/casio-e55/setup.c linux-2.4.29-pre3/arch/mips/vr41xx/casio-e55/setup.c
--- linux-2.4.28/arch/mips/vr41xx/casio-e55/setup.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/vr41xx/casio-e55/setup.c	2004-12-22 16:05:54.972062304 +0000
@@ -1,33 +1,31 @@
 /*
- * FILE NAME
- *	arch/mips/vr41xx/casio-e55/setup.c
+ *  setup.c, Setup for the CASIO CASSIOPEIA E-11/15/55/65.
  *
- * BRIEF MODULE DESCRIPTION
- *	Setup for the CASIO CASSIOPEIA E-11/15/55/65.
+ *  Copyright (C) 2002-2004  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
  *
- * Copyright 2002 Yoichi Yuasa
- *                yuasa@hh.iij4u.or.jp
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
  *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms of the GNU General Public License as published by the
- *  Free Software Foundation; either version 2 of the License, or (at your
- *  option) any later version.
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <linux/config.h>
-#include <linux/init.h>
 #include <linux/console.h>
 #include <linux/ide.h>
+#include <linux/init.h>
 #include <linux/ioport.h>
 
-#include <asm/reboot.h>
 #include <asm/time.h>
 #include <asm/vr41xx/e55.h>
 
-#ifdef CONFIG_BLK_DEV_INITRD
-extern unsigned long initrd_start, initrd_end;
-extern void * __rd_start, * __rd_end;
-#endif
-
 void __init casio_e55_setup(void)
 {
 	set_io_port_base(IO_PORT_BASE);
@@ -36,16 +34,6 @@ void __init casio_e55_setup(void)
 	iomem_resource.start = IO_MEM_RESOURCE_START;
 	iomem_resource.end = IO_MEM_RESOURCE_END;
 
-#ifdef CONFIG_BLK_DEV_INITRD
-	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
-	initrd_start = (unsigned long)&__rd_start;
-	initrd_end = (unsigned long)&__rd_end;
-#endif
-
-	_machine_restart = vr41xx_restart;
-	_machine_halt = vr41xx_halt;
-	_machine_power_off = vr41xx_power_off;
-
 	board_time_init = vr41xx_time_init;
 	board_timer_setup = vr41xx_timer_setup;
 
@@ -58,8 +46,10 @@ void __init casio_e55_setup(void)
 #endif
 
 	vr41xx_bcu_init();
-
 	vr41xx_cmu_init();
+	vr41xx_pmu_init();
 
+#ifdef CONFIG_SERIAL
 	vr41xx_siu_init(SIU_RS232C, 0);
+#endif
 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/vr41xx/common/Makefile linux-2.4.29-pre3/arch/mips/vr41xx/common/Makefile
--- linux-2.4.28/arch/mips/vr41xx/common/Makefile	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/vr41xx/common/Makefile	2004-12-22 16:06:42.331862520 +0000
@@ -12,7 +12,7 @@ all: vr41xx.o
 
 O_TARGET := vr41xx.o
 
-obj-y := bcu.o cmu.o giu.o icu.o int-handler.o ksyms.o reset.o rtc.o
+obj-y := bcu.o cmu.o giu.o icu.o int-handler.o ksyms.o pmu.o rtc.o
 
 export-objs := ksyms.o vrc4171.o vrc4173.o
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/vr41xx/common/cmu.c linux-2.4.29-pre3/arch/mips/vr41xx/common/cmu.c
--- linux-2.4.28/arch/mips/vr41xx/common/cmu.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/vr41xx/common/cmu.c	2004-12-22 16:05:31.466635672 +0000
@@ -40,6 +40,7 @@
  *  - Added support for NEC VR4133.
  */
 #include <linux/init.h>
+#include <linux/spinlock.h>
 #include <linux/types.h>
 
 #include <asm/cpu.h>
@@ -66,16 +67,19 @@
  #define MSKMAC0	0x0002
  #define MSKMAC1	0x0004
 
-static u32 vr41xx_cmu_base;
-static u16 cmuclkmsk, cmuclkmsk2;
+static uint32_t cmu_base;
+static uint16_t cmuclkmsk, cmuclkmsk2;
+static spinlock_t cmu_lock;
 
-#define read_cmuclkmsk()	readw(vr41xx_cmu_base)
+#define read_cmuclkmsk()	readw(cmu_base)
 #define read_cmuclkmsk2()	readw(CMUCLKMSK2)
-#define write_cmuclkmsk()	writew(cmuclkmsk, vr41xx_cmu_base)
+#define write_cmuclkmsk()	writew(cmuclkmsk, cmu_base)
 #define write_cmuclkmsk2()	writew(cmuclkmsk2, CMUCLKMSK2)
 
-void vr41xx_clock_supply(unsigned int clock)
+void vr41xx_supply_clock(unsigned int clock)
 {
+	spin_lock_irq(&cmu_lock);
+
 	switch (clock) {
 	case PIU_CLOCK:
 		cmuclkmsk |= MSKPIU;
@@ -129,10 +133,14 @@ void vr41xx_clock_supply(unsigned int cl
 		write_cmuclkmsk2();
 	else
 		write_cmuclkmsk();
+
+	spin_unlock_irq(&cmu_lock);
 }
 
-void vr41xx_clock_mask(unsigned int clock)
+void vr41xx_mask_clock(unsigned int clock)
 {
+	spin_lock_irq(&cmu_lock);
+
 	switch (clock) {
 	case PIU_CLOCK:
 		cmuclkmsk &= ~MSKPIU;
@@ -198,6 +206,8 @@ void vr41xx_clock_mask(unsigned int cloc
 		write_cmuclkmsk2();
 	else
 		write_cmuclkmsk();
+
+	spin_unlock_irq(&cmu_lock);
 }
 
 void __init vr41xx_cmu_init(void)
@@ -205,14 +215,14 @@ void __init vr41xx_cmu_init(void)
 	switch (current_cpu_data.cputype) {
         case CPU_VR4111:
         case CPU_VR4121:
-                vr41xx_cmu_base = CMUCLKMSK_TYPE1;
+                cmu_base = CMUCLKMSK_TYPE1;
                 break;
         case CPU_VR4122:
         case CPU_VR4131:
-                vr41xx_cmu_base = CMUCLKMSK_TYPE2;
+                cmu_base = CMUCLKMSK_TYPE2;
                 break;
         case CPU_VR4133:
-                vr41xx_cmu_base = CMUCLKMSK_TYPE2;
+                cmu_base = CMUCLKMSK_TYPE2;
 		cmuclkmsk2 = read_cmuclkmsk2();
                 break;
 	default:
@@ -221,4 +231,6 @@ void __init vr41xx_cmu_init(void)
         }
 
 	cmuclkmsk = read_cmuclkmsk();
+
+	spin_lock_init(&cmu_lock);
 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/vr41xx/common/ksyms.c linux-2.4.29-pre3/arch/mips/vr41xx/common/ksyms.c
--- linux-2.4.28/arch/mips/vr41xx/common/ksyms.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/vr41xx/common/ksyms.c	2004-12-22 16:07:42.026787512 +0000
@@ -25,6 +25,9 @@
 EXPORT_SYMBOL(vr41xx_get_vtclock_frequency);
 EXPORT_SYMBOL(vr41xx_get_tclock_frequency);
 
+EXPORT_SYMBOL(vr41xx_supply_clock);
+EXPORT_SYMBOL(vr41xx_mask_clock);
+
 EXPORT_SYMBOL(vr41xx_set_intassign);
 
 EXPORT_SYMBOL(vr41xx_set_rtclong1_cycle);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/vr41xx/common/pciu.c linux-2.4.29-pre3/arch/mips/vr41xx/common/pciu.c
--- linux-2.4.28/arch/mips/vr41xx/common/pciu.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/vr41xx/common/pciu.c	2004-12-22 16:06:21.303059384 +0000
@@ -1,40 +1,17 @@
 /*
- * FILE NAME
- *	arch/mips/vr41xx/common/pciu.c
+ * arch/mips/vr41xx/common/pciu.c
  *
- * BRIEF MODULE DESCRIPTION
- *	PCI Control Unit routines for the NEC VR4100 series.
+ * PCI Control Unit routines for the NEC VR4100 series.
  *
- * Author: Yoichi Yuasa
- *         yyuasa@mvista.com or source@mvista.com
+ * Author: Yoichi Yuasa <yyuasa@mvista.com, or source@mvista.com>
  *
- * Copyright 2001,2002 MontaVista Software Inc.
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms of the GNU General Public License as published by the
- *  Free Software Foundation; either version 2 of the License, or (at your
- *  option) any later version.
- *
- *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
+ * 2001-2003 (c) MontaVista, Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 /*
  * Changes:
- *  Paul Mundt <lethal@chaoticdreams.org>
- *  - Fix deadlock-causing PCIU access race for VR4131.
- *
  *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
  *  - New creation, NEC VR4122 and VR4131 are supported.
  */
@@ -42,7 +19,6 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/types.h>
-#include <linux/delay.h>
 
 #include <asm/cpu.h>
 #include <asm/io.h>
@@ -60,49 +36,48 @@ static inline int vr41xx_pci_config_acce
 		/*
 		 * Type 0 configuration
 		 */
-		if (PCI_SLOT(dev_fn) < 11 || PCI_SLOT(dev_fn) > 31 || where > 255)
-			return -1;
+		if (PCI_SLOT(dev_fn) < 11 || PCI_SLOT(dev_fn) > 31 || where > 0xff)
+			return -EINVAL;
 
-		writel((1UL << PCI_SLOT(dev_fn))|
+		writel((1U << PCI_SLOT(dev_fn))	|
 		       (PCI_FUNC(dev_fn) << 8)	|
 		       (where & 0xfc),
 		       PCICONFAREG);
-	}
-	else {
+	} else {
 		/*
 		 * Type 1 configuration
 		 */
-		if (PCI_SLOT(dev_fn) > 31 || where > 255)
-			return -1;
+		if (PCI_SLOT(dev_fn) > 31 || where > 0xff)
+			return -EINVAL;
 
 		writel((bus << 16)	|
 		       (dev_fn << 8)	|
 		       (where & 0xfc)	|
-		       1UL,
+		       1U,
 		       PCICONFAREG);
 	}
 
 	return 0;
 }
 
-static int vr41xx_pci_read_config_byte(struct pci_dev *dev, int where, u8 *val)
+static int vr41xx_pci_config_read_byte(struct pci_dev *dev, int where, uint8_t *val)
 {
-	u32 data;
+	uint32_t data;
 
 	*val = 0xff;
 	if (vr41xx_pci_config_access(dev, where) < 0)
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
 	data = readl(PCICONFDREG);
-	*val = (u8)(data >> ((where & 3) << 3));
+	*val = (uint8_t)(data >> ((where & 3) << 3));
 
 	return PCIBIOS_SUCCESSFUL;
 
 }
 
-static int vr41xx_pci_read_config_word(struct pci_dev *dev, int where, u16 *val)
+static int vr41xx_pci_config_read_word(struct pci_dev *dev, int where, uint16_t *val)
 {
-	u32 data;
+	uint32_t data;
 
 	*val = 0xffff;
 	if (where & 1)
@@ -112,12 +87,12 @@ static int vr41xx_pci_read_config_word(s
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
 	data = readl(PCICONFDREG);
-	*val = (u16)(data >> ((where & 2) << 3));
+	*val = (uint16_t)(data >> ((where & 2) << 3));
 
 	return PCIBIOS_SUCCESSFUL;
 }
 
-static int vr41xx_pci_read_config_dword(struct pci_dev *dev, int where, u32 *val)
+static int vr41xx_pci_config_read_dword(struct pci_dev *dev, int where, uint32_t *val)
 {
 	*val = 0xffffffff;
 	if (where & 3)
@@ -131,9 +106,9 @@ static int vr41xx_pci_read_config_dword(
 	return PCIBIOS_SUCCESSFUL;
 }
 
-static int vr41xx_pci_write_config_byte(struct pci_dev *dev, int where, u8 val)
+static int vr41xx_pci_config_write_byte(struct pci_dev *dev, int where, uint8_t val)
 {
-	u32 data;
+	uint32_t data;
 	int shift;
 
 	if (vr41xx_pci_config_access(dev, where) < 0)
@@ -141,17 +116,16 @@ static int vr41xx_pci_write_config_byte(
 
 	data = readl(PCICONFDREG);
 	shift = (where & 3) << 3;
-	data &= ~(0xff << shift);
-	data |= (((u32)val) << shift);
-
+	data &= ~(0xffU << shift);
+	data |= (uint32_t)val << shift;
 	writel(data, PCICONFDREG);
 
 	return PCIBIOS_SUCCESSFUL;
 }
 
-static int vr41xx_pci_write_config_word(struct pci_dev *dev, int where, u16 val)
+static int vr41xx_pci_config_write_word(struct pci_dev *dev, int where, uint16_t val)
 {
-	u32 data;
+	uint32_t data;
 	int shift;
 
 	if (where & 1)
@@ -162,14 +136,14 @@ static int vr41xx_pci_write_config_word(
 
 	data = readl(PCICONFDREG);
 	shift = (where & 2) << 3;
-	data &= ~(0xffff << shift);
-	data |= (((u32)val) << shift);
+	data &= ~(0xffffU << shift);
+	data |= (uint32_t)val << shift;
 	writel(data, PCICONFDREG);
 
 	return PCIBIOS_SUCCESSFUL;
 }
 
-static int vr41xx_pci_write_config_dword(struct pci_dev *dev, int where, u32 val)
+static int vr41xx_pci_config_write_dword(struct pci_dev *dev, int where, uint32_t val)
 {
 	if (where & 3)
 		return PCIBIOS_BAD_REGISTER_NUMBER;
@@ -183,35 +157,32 @@ static int vr41xx_pci_write_config_dword
 }
 
 struct pci_ops vr41xx_pci_ops = {
-	vr41xx_pci_read_config_byte,
-	vr41xx_pci_read_config_word,
-	vr41xx_pci_read_config_dword,
-	vr41xx_pci_write_config_byte,
-	vr41xx_pci_write_config_word,
-	vr41xx_pci_write_config_dword
+	.read_byte	= vr41xx_pci_config_read_byte,
+	.read_word	= vr41xx_pci_config_read_word,
+	.read_dword	= vr41xx_pci_config_read_dword,
+	.write_byte	= vr41xx_pci_config_write_byte,
+	.write_word	= vr41xx_pci_config_write_word,
+	.write_dword	= vr41xx_pci_config_write_dword,
 };
 
 void __init vr41xx_pciu_init(struct vr41xx_pci_address_map *map)
 {
 	struct vr41xx_pci_address_space *s;
 	unsigned long vtclock;
-	u32 config;
-	int n;
+	uint32_t config;
 
-	if (!map)
+	if (map == NULL)
 		return;
 
 	/* Disable PCI interrupt */
 	writew(0, MPCIINTREG);
 
 	/* Supply VTClock to PCIU */
-	vr41xx_clock_supply(PCIU_CLOCK);
+	vr41xx_supply_clock(PCIU_CLOCK);
 
-	/*
-	 * Sleep for 1us after setting MSKPPCIU bit in CMUCLKMSK
-	 * before doing any PCIU access to avoid deadlock on VR4131.
-	 */
-	udelay(1);
+	/* Dummy read/write, waiting for supply of VTClock. */
+	readw(MPCIINTREG);
+	writew(0, MPCIINTREG);
 
 	/* Select PCI clock */
 	vtclock = vr41xx_get_vtclock_frequency();
@@ -225,7 +196,7 @@ void __init vr41xx_pciu_init(struct vr41
 		printk(KERN_INFO "Warning: PCI Clock is over 33MHz.\n");
 
 	/* Supply PCI clock by PCI bus */
-	vr41xx_clock_supply(PCI_CLOCK);
+	vr41xx_supply_clock(PCI_CLOCK);
 
 	/*
 	 * Set PCI memory & I/O space address conversion registers
@@ -233,48 +204,52 @@ void __init vr41xx_pciu_init(struct vr41
 	 */
 	if (map->mem1 != NULL) {
 		s = map->mem1;
-		config = (s->internal_base & 0xff000000) |
-		         ((s->address_mask & 0x7f000000) >> 11) | (1UL << 12) |
-		         ((s->pci_base & 0xff000000) >> 24);
+		config = (s->internal_base & INTERNAL_BUS_BASE_ADDRESS)	|
+		         ((s->address_mask >> 11) & ADDRESS_MASK)	|
+		         PCI_ACCESS_ENABLE				|
+		         ((s->pci_base >> 24) & PCI_ADDRESS_SETTING);
 		writel(config, PCIMMAW1REG);
 	}
 	if (map->mem2 != NULL) {
 		s = map->mem2;
-		config = (s->internal_base & 0xff000000) |
-		         ((s->address_mask & 0x7f000000) >> 11) | (1UL << 12) |
-		         ((s->pci_base & 0xff000000) >> 24);
+		config = (s->internal_base & INTERNAL_BUS_BASE_ADDRESS)	|
+		         ((s->address_mask >> 11) & ADDRESS_MASK)	|
+		         PCI_ACCESS_ENABLE				|
+		         ((s->pci_base >> 24) & PCI_ADDRESS_SETTING);
 		writel(config, PCIMMAW2REG);
 	}
 	if (map->io != NULL) {
 		s = map->io;
-		config = (s->internal_base & 0xff000000) |
-		         ((s->address_mask & 0x7f000000) >> 11) | (1UL << 12) |
-		         ((s->pci_base & 0xff000000) >> 24);
+		config = (s->internal_base & INTERNAL_BUS_BASE_ADDRESS) |
+		         ((s->address_mask >> 11) & ADDRESS_MASK) |
+		         PCI_ACCESS_ENABLE |
+		         ((s->pci_base >> 24) & PCI_ADDRESS_SETTING);
 		writel(config, PCIMIOAWREG);
 	}
 
 	/* Set target memory windows */
-	writel(0x00081000, PCITAW1REG);
-	writel(0UL, PCITAW2REG);
-	pciu_write_config_dword(PCI_BASE_ADDRESS_0, 0UL);
-	pciu_write_config_dword(PCI_BASE_ADDRESS_1, 0UL);
+	writel(0x00081000U, PCITAW1REG);
+	writel(0U, PCITAW2REG);
+
+	pciu_write_config_dword(PCI_BASE_ADDRESS_0, 0U);
+	pciu_write_config_dword(PCI_BASE_ADDRESS_1, 0U);
 
 	/* Clear bus error */
-	n = readl(BUSERRADREG);
+	readl(BUSERRADREG);
 
 	if (current_cpu_data.cputype == CPU_VR4122) {
-		writel(0UL, PCITRDYVREG);
-		pciu_write_config_dword(PCI_CACHE_LINE_SIZE, 0x0000f804);
+		writel(0U, PCITRDYVREG);
+		pciu_write_config_byte(PCI_LATENCY_TIMER, 0xf8);
 	} else {
-		writel(100UL, PCITRDYVREG);
-		pciu_write_config_dword(PCI_CACHE_LINE_SIZE, 0x00008004);
+		writel(100U, PCITRDYVREG);
+		pciu_write_config_byte(PCI_LATENCY_TIMER, 0x80);
 	}
 
 	writel(CONFIG_DONE, PCIENREG);
-	pciu_write_config_dword(PCI_COMMAND,
-	                        PCI_COMMAND_IO |
-	                        PCI_COMMAND_MEMORY |
-	                        PCI_COMMAND_MASTER |
-	                        PCI_COMMAND_PARITY |
-	                        PCI_COMMAND_SERR);
+	pciu_write_config_word(PCI_COMMAND,
+	                       PCI_COMMAND_IO |
+	                       PCI_COMMAND_MEMORY |
+	                       PCI_COMMAND_MASTER |
+	                       PCI_COMMAND_PARITY |
+	                       PCI_COMMAND_SERR);
 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/vr41xx/common/pciu.h linux-2.4.29-pre3/arch/mips/vr41xx/common/pciu.h
--- linux-2.4.28/arch/mips/vr41xx/common/pciu.h	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/vr41xx/common/pciu.h	2004-12-22 16:07:18.909301904 +0000
@@ -1,34 +1,14 @@
 /*
- * FILE NAME
- *	arch/mips/vr41xx/common/pciu.h
+ * arch/mips/vr41xx/common/pciu.h
  *
- * BRIEF MODULE DESCRIPTION
- *	Include file for PCI Control Unit of the NEC VR4100 series.
+ * Include file for PCI Control Unit of the NEC VR4100 series.
  *
- * Author: Yoichi Yuasa
- *         yyuasa@mvista.com or source@mvista.com
+ * Author: Yoichi Yuasa <yyuasa@mvista.com, or source@mvista.com>
  *
- * Copyright 2002 MontaVista Software Inc.
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms of the GNU General Public License as published by the
- *  Free Software Foundation; either version 2 of the License, or (at your
- *  option) any later version.
- *
- *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
+ * 2002-2003 (c) MontaVista, Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 /*
  * Changes:
@@ -41,24 +21,24 @@
 #include <linux/config.h>
 #include <asm/addrspace.h>
 
-#define BIT(x)	(1 << (x))
+#define BIT(x)	(1U << (x))
 
 #define PCIMMAW1REG			KSEG1ADDR(0x0f000c00)
 #define PCIMMAW2REG			KSEG1ADDR(0x0f000c04)
 #define PCITAW1REG			KSEG1ADDR(0x0f000c08)
 #define PCITAW2REG			KSEG1ADDR(0x0f000c0c)
 #define PCIMIOAWREG			KSEG1ADDR(0x0f000c10)
-#define INTERNAL_BUS_BASE_ADDRESS	0xff000000
-#define ADDRESS_MASK			0x000fe000
+#define INTERNAL_BUS_BASE_ADDRESS	0xff000000U
+#define ADDRESS_MASK			0x000fe000U
 #define PCI_ACCESS_ENABLE		BIT(12)
-#define PCI_ADDRESS_SETTING		0x000000ff
+#define PCI_ADDRESS_SETTING		0x000000ffU
 
 #define PCICONFDREG			KSEG1ADDR(0x0f000c14)
 #define PCICONFAREG			KSEG1ADDR(0x0f000c18)
 #define PCIMAILREG			KSEG1ADDR(0x0f000c1c)
 
 #define BUSERRADREG			KSEG1ADDR(0x0f000c24)
-#define ERROR_ADDRESS			0xfffffffc
+#define ERROR_ADDRESS			0xfffffffcU
 
 #define INTCNTSTAREG			KSEG1ADDR(0x0f000c28)
 #define MABTCLR				BIT(31)
@@ -72,91 +52,102 @@
 #define EAREQ				BIT(0)
 
 #define PCIRECONTREG			KSEG1ADDR(0x0f000c30)
-#define RTRYCNT				0x000000ff
+#define RTRYCNT				0xffU
 
 #define PCIENREG			KSEG1ADDR(0x0f000c34)
 #define CONFIG_DONE			BIT(2)
 
 #define PCICLKSELREG			KSEG1ADDR(0x0f000c38)
-#define EQUAL_VTCLOCK			0x00000002
-#define HALF_VTCLOCK			0x00000000
-#define QUARTER_VTCLOCK			0x00000001
+#define EQUAL_VTCLOCK			0x2U
+#define HALF_VTCLOCK			0x0U
+#define QUARTER_VTCLOCK			0x1U
 
 #define PCITRDYVREG			KSEG1ADDR(0x0f000c3c)
 
 #define PCICLKRUNREG			KSEG1ADDR(0x0f000c60)
 
-#define PCIU_CONFIGREGS_BASE		KSEG1ADDR(0x0f000d00)
 #define VENDORIDREG			KSEG1ADDR(0x0f000d00)
-#define DEVICEIDREG			KSEG1ADDR(0x0f000d00)
-#define COMMANDREG			KSEG1ADDR(0x0f000d04)
-#define STATUSREG			KSEG1ADDR(0x0f000d04)
-#define REVIDREG			KSEG1ADDR(0x0f000d08)
-#define CLASSREG			KSEG1ADDR(0x0f000d08)
-#define CACHELSREG			KSEG1ADDR(0x0f000d0c)
-#define LATTIMEREG			KSEG1ADDR(0x0f000d0c)
-#define MAILBAREG			KSEG1ADDR(0x0f000d10)
-#define PCIMBA1REG			KSEG1ADDR(0x0f000d14)
-#define PCIMBA2REG			KSEG1ADDR(0x0f000d18)
-#define INTLINEREG			KSEG1ADDR(0x0f000d3c)
-#define INTPINREG			KSEG1ADDR(0x0f000d3c)
-#define RETVALREG			KSEG1ADDR(0x0f000d40)
-#define PCIAPCNTREG			KSEG1ADDR(0x0f000d40)
 
 #define MPCIINTREG			KSEG1ADDR(0x0f0000b2)
 
 #define MAX_PCI_CLOCK			33333333
 
-static inline int pciu_read_config_byte(int where, u8 *val)
+static inline int pciu_read_config_byte(int where, uint8_t *val)
 {
-	u32 data;
+	uint32_t data;
 
-	data = readl(PCIU_CONFIGREGS_BASE + where);
-	*val = (u8)(data >> ((where & 3) << 3));
+	if (where > 0xff)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	data = readl(VENDORIDREG + (where & 0xfc));
+	*val = (uint8_t)(data >> ((where & 3) << 3));
 
 	return PCIBIOS_SUCCESSFUL;
 }
 
-static inline int pciu_read_config_word(int where, u16 *val)
+static inline int pciu_read_config_word(int where, uint16_t *val)
 {
-	u32 data;
+	uint32_t data;
 
-	if (where & 1)
+	if (where > 0xff || (where & 1))
 		return PCIBIOS_BAD_REGISTER_NUMBER;
 
-	data = readl(PCIU_CONFIGREGS_BASE + where);
-	*val = (u16)(data >> ((where & 2) << 3));
+	data = readl(VENDORIDREG + (where & 0xfc));
+	*val = (uint16_t)(data >> ((where & 2) << 3));
 
 	return PCIBIOS_SUCCESSFUL;
 }
 
-static inline int pciu_read_config_dword(int where, u32 *val)
+static inline int pciu_read_config_dword(int where, uint32_t *val)
 {
-	if (where & 3)
+	if (where > 0xff || (where & 3))
 		return PCIBIOS_BAD_REGISTER_NUMBER;
 
-	*val = readl(PCIU_CONFIGREGS_BASE + where);
+	*val = readl(VENDORIDREG + where);
 
 	return PCIBIOS_SUCCESSFUL;
 }
 
-static inline int pciu_write_config_byte(int where, u8 val)
+static inline int pciu_write_config_byte(int where, uint8_t val)
 {
-	writel(val, PCIU_CONFIGREGS_BASE + where);
+	uint32_t data;
+	int shift;
+
+	if (where > 0xff)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	data = readl(VENDORIDREG + (where & 0xfc));
+	shift = (where & 3) << 3;
+	data &= ~(0xffU << shift);
+	data |= (uint32_t)val << shift;
+	writel(data, VENDORIDREG + (where & 0xfc));
 
 	return 0;
 }
 
-static inline int pciu_write_config_word(int where, u16 val)
+static inline int pciu_write_config_word(int where, uint16_t val)
 {
-	writel(val, PCIU_CONFIGREGS_BASE + where);
+	uint32_t data;
+	int shift;
+
+	if (where > 0xff || (where & 1))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	data = readl(VENDORIDREG + (where & 0xfc));
+	shift = (where & 2) << 3;
+	data &= ~(0xffffU << shift);
+	data |= (uint32_t)val << shift;
+	writel(data, VENDORIDREG + (where & 0xfc));
 
 	return 0;
 }
 
-static inline int pciu_write_config_dword(int where, u32 val)
+static inline int pciu_write_config_dword(int where, uint32_t val)
 {
-	writel(val, PCIU_CONFIGREGS_BASE + where);
+	if (where > 0xff || (where & 3))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	writel(val, VENDORIDREG + where);
 
 	return 0;
 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/vr41xx/common/pmu.c linux-2.4.29-pre3/arch/mips/vr41xx/common/pmu.c
--- linux-2.4.28/arch/mips/vr41xx/common/pmu.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/vr41xx/common/pmu.c	2004-12-22 16:06:44.774491184 +0000
@@ -0,0 +1,75 @@
+/*
+ *  pmu.c, Power Management Unit routines for NEC VR4100 series.
+ *
+ *  Copyright (C) 2003  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include <asm/cpu.h>
+#include <asm/io.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+
+#define PMUCNT2REG	KSEG1ADDR(0x0f0000c6)
+ #define SOFTRST	0x0010
+
+static inline void software_reset(void)
+{
+	uint16_t val;
+
+	switch (current_cpu_data.cputype) {
+	case CPU_VR4122:
+	case CPU_VR4131:
+	case CPU_VR4133:
+		val = readw(PMUCNT2REG);
+		val |= SOFTRST;
+		writew(val, PMUCNT2REG);
+		break;
+	default:
+		break;
+	}
+}
+
+static void vr41xx_restart(char *command)
+{
+	local_irq_disable();
+	software_reset();
+	printk(KERN_NOTICE "\nYou can reset your system\n");
+	while (1) ;
+}
+
+static void vr41xx_halt(void)
+{
+	local_irq_disable();
+	printk(KERN_NOTICE "\nYou can turn off the power supply\n");
+	while (1) ;
+}
+
+static void vr41xx_power_off(void)
+{
+	local_irq_disable();
+	printk(KERN_NOTICE "\nYou can turn off the power supply\n");
+	while (1) ;
+}
+
+void __init vr41xx_pmu_init(void)
+{
+	_machine_restart = vr41xx_restart;
+	_machine_halt = vr41xx_halt;
+	_machine_power_off = vr41xx_power_off;
+}
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/vr41xx/common/serial.c linux-2.4.29-pre3/arch/mips/vr41xx/common/serial.c
--- linux-2.4.28/arch/mips/vr41xx/common/serial.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/vr41xx/common/serial.c	2004-12-22 16:07:18.909301904 +0000
@@ -145,7 +145,7 @@ void __init vr41xx_siu_init(int interfac
 	if (early_serial_setup(&s) != 0)
 		printk(KERN_ERR "SIU setup failed!\n");
 
-	vr41xx_clock_supply(SIU_CLOCK);
+	vr41xx_supply_clock(SIU_CLOCK);
 
 	vr41xx_serial_ports++;
 }
@@ -171,7 +171,7 @@ void __init vr41xx_dsiu_init(void)
 	if (early_serial_setup(&s) != 0)
 		printk(KERN_ERR "DSIU setup failed!\n");
 
-	vr41xx_clock_supply(DSIU_CLOCK);
+	vr41xx_supply_clock(DSIU_CLOCK);
 
 	writew(INTDSIU, MDSIUINTREG);
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/vr41xx/common/vrc4173.c linux-2.4.29-pre3/arch/mips/vr41xx/common/vrc4173.c
--- linux-2.4.28/arch/mips/vr41xx/common/vrc4173.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/vr41xx/common/vrc4173.c	2004-12-22 16:05:30.881724592 +0000
@@ -1,34 +1,14 @@
 /*
- * FILE NAME
- *	drivers/char/vrc4173.c
- * 
- * BRIEF MODULE DESCRIPTION
- *	NEC VRC4173 driver for NEC VR4122/VR4131.
+ * arch/mips/vr41xx/common/vrc4173.c
  *
- * Author: Yoichi Yuasa
- *         yyuasa@mvista.com or source@mvista.com
+ * NEC VRC4173 driver for NEC VR4122/VR4131.
  *
- * Copyright 2001,2002 MontaVista Software Inc.
+ * Author: Yoichi Yuasa <yyuasa@mvista.com, or source@mvista.com>
  *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms of the GNU General Public License as published by the
- *  Free Software Foundation; either version 2 of the License, or (at your
- *  option) any later version.
- *
- *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
+ * 2001-2003 (c) MontaVista, Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 #include <linux/config.h>
 #include <linux/init.h>
@@ -36,6 +16,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/pci.h>
+#include <linux/spinlock.h>
 #include <linux/types.h>
 
 #include <asm/vr41xx/vr41xx.h>
@@ -45,100 +26,292 @@ MODULE_DESCRIPTION("NEC VRC4173 driver f
 MODULE_AUTHOR("Yoichi Yuasa <yyuasa@mvista.com>");
 MODULE_LICENSE("GPL");
 
+EXPORT_SYMBOL(vrc4173_io_offset);
+EXPORT_SYMBOL(vrc4173_supply_clock);
+EXPORT_SYMBOL(vrc4173_mask_clock);
+EXPORT_SYMBOL(vrc4173_select_function);
+
 #define VRC4173_CMUCLKMSK	0x040
+ #define MSKPIU			0x0001
+ #define MSKKIU			0x0002
+ #define MSKAIU			0x0004
+ #define MSKPS2CH1		0x0008
+ #define MSKPS2CH2		0x0010
+ #define MSKUSB			0x0020
+ #define MSKCARD1		0x0040
+ #define MSKCARD2		0x0080
+ #define MSKAC97		0x0100
+ #define MSK48MUSB		0x0400
+ #define MSK48MPIN		0x0800
+ #define MSK48MOSC		0x1000
 #define VRC4173_CMUSRST		0x042
-
-#define VRC4173_SELECTREG	0x09e
+ #define USBRST			0x0001
+ #define CARD1RST		0x0002
+ #define CARD2RST		0x0004
+ #define AC97RST		0x0008
 
 #define VRC4173_SYSINT1REG	0x060
 #define VRC4173_MSYSINT1REG	0x06c
 
+#define VRC4173_SELECTREG	0x09e
+
 static struct pci_device_id vrc4173_table[] __devinitdata = {
-	{PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_VRC4173, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0, }
+	{	.vendor		= PCI_VENDOR_ID_NEC,
+		.device		= PCI_DEVICE_ID_NEC_VRC4173,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,			},
+	{	.vendor		= 0,				},
 };
 
 unsigned long vrc4173_io_offset = 0;
 
-EXPORT_SYMBOL(vrc4173_io_offset);
-
-static u16 vrc4173_cmuclkmsk;
 static int vrc4173_initialized;
+static uint16_t vrc4173_cmuclkmsk;
+static uint16_t vrc4173_selectreg;
+static spinlock_t vrc4173_cmu_lock;
+static spinlock_t vrc4173_giu_lock;
 
-void vrc4173_clock_supply(u16 mask)
+static inline void set_cmusrst(uint16_t val)
+{
+	uint16_t cmusrst;
+
+	cmusrst = vrc4173_inw(VRC4173_CMUSRST);
+	cmusrst |= val;
+	vrc4173_outw(cmusrst, VRC4173_CMUSRST);
+}
+
+static inline void clear_cmusrst(uint16_t val)
+{
+	uint16_t cmusrst;
+
+	cmusrst = vrc4173_inw(VRC4173_CMUSRST);
+	cmusrst &= ~val;
+	vrc4173_outw(cmusrst, VRC4173_CMUSRST);
+}
+
+void vrc4173_supply_clock(unsigned int clock)
 {
 	if (vrc4173_initialized) {
-		vrc4173_cmuclkmsk |= mask;
+		spin_lock_irq(&vrc4173_cmu_lock);
+
+		switch (clock) {
+		case VRC4173_PIU_CLOCK:
+			vrc4173_cmuclkmsk |= MSKPIU;
+			break;
+		case VRC4173_KIU_CLOCK:
+			vrc4173_cmuclkmsk |= MSKKIU;
+			break;
+		case VRC4173_AIU_CLOCK:
+			vrc4173_cmuclkmsk |= MSKAIU;
+			break;
+		case VRC4173_PS2_CH1_CLOCK:
+			vrc4173_cmuclkmsk |= MSKPS2CH1;
+			break;
+		case VRC4173_PS2_CH2_CLOCK:
+			vrc4173_cmuclkmsk |= MSKPS2CH2;
+			break;
+		case VRC4173_USBU_PCI_CLOCK:
+			set_cmusrst(USBRST);
+			vrc4173_cmuclkmsk |= MSKUSB;
+			break;
+		case VRC4173_CARDU1_PCI_CLOCK:
+			set_cmusrst(CARD1RST);
+			vrc4173_cmuclkmsk |= MSKCARD1;
+			break;
+		case VRC4173_CARDU2_PCI_CLOCK:
+			set_cmusrst(CARD2RST);
+			vrc4173_cmuclkmsk |= MSKCARD2;
+			break;
+		case VRC4173_AC97U_PCI_CLOCK:
+			set_cmusrst(AC97RST);
+			vrc4173_cmuclkmsk |= MSKAC97;
+			break;
+		case VRC4173_USBU_48MHz_CLOCK:
+			set_cmusrst(USBRST);
+			vrc4173_cmuclkmsk |= MSK48MUSB;
+			break;
+		case VRC4173_EXT_48MHz_CLOCK:
+			if (vrc4173_cmuclkmsk & MSK48MOSC)
+				vrc4173_cmuclkmsk |= MSK48MPIN;
+			else
+				printk(KERN_WARNING
+				       "vrc4173_supply_clock: "
+				       "Please supply VRC4173_48MHz_CLOCK first "
+				       "rather than VRC4173_EXT_48MHz_CLOCK.\n");
+			break;
+		case VRC4173_48MHz_CLOCK:
+			vrc4173_cmuclkmsk |= MSK48MOSC;
+			break;
+		default:
+			printk(KERN_WARNING
+			       "vrc4173_supply_clock: Invalid CLOCK value %u\n", clock);
+			break;
+		}
+
 		vrc4173_outw(vrc4173_cmuclkmsk, VRC4173_CMUCLKMSK);
+
+		switch (clock) {
+		case VRC4173_USBU_PCI_CLOCK:
+		case VRC4173_USBU_48MHz_CLOCK:
+			clear_cmusrst(USBRST);
+			break;
+		case VRC4173_CARDU1_PCI_CLOCK:
+			clear_cmusrst(CARD1RST);
+			break;
+		case VRC4173_CARDU2_PCI_CLOCK:
+			clear_cmusrst(CARD2RST);
+			break;
+		case VRC4173_AC97U_PCI_CLOCK:
+			clear_cmusrst(AC97RST);
+			break;
+		default:
+			break;
+		}
+
+		spin_unlock_irq(&vrc4173_cmu_lock);
 	}
 }
 
-void vrc4173_clock_mask(u16 mask)
+void vrc4173_mask_clock(unsigned int clock)
 {
 	if (vrc4173_initialized) {
-		vrc4173_cmuclkmsk &= ~mask;
+		spin_lock_irq(&vrc4173_cmu_lock);
+
+		switch (clock) {
+		case VRC4173_PIU_CLOCK:
+			vrc4173_cmuclkmsk &= ~MSKPIU;
+			break;
+		case VRC4173_KIU_CLOCK:
+			vrc4173_cmuclkmsk &= ~MSKKIU;
+			break;
+		case VRC4173_AIU_CLOCK:
+			vrc4173_cmuclkmsk &= ~MSKAIU;
+			break;
+		case VRC4173_PS2_CH1_CLOCK:
+			vrc4173_cmuclkmsk &= ~MSKPS2CH1;
+			break;
+		case VRC4173_PS2_CH2_CLOCK:
+			vrc4173_cmuclkmsk &= ~MSKPS2CH2;
+			break;
+		case VRC4173_USBU_PCI_CLOCK:
+			set_cmusrst(USBRST);
+			vrc4173_cmuclkmsk &= ~MSKUSB;
+			break;
+		case VRC4173_CARDU1_PCI_CLOCK:
+			set_cmusrst(CARD1RST);
+			vrc4173_cmuclkmsk &= ~MSKCARD1;
+			break;
+		case VRC4173_CARDU2_PCI_CLOCK:
+			set_cmusrst(CARD2RST);
+			vrc4173_cmuclkmsk &= ~MSKCARD2;
+			break;
+		case VRC4173_AC97U_PCI_CLOCK:
+			set_cmusrst(AC97RST);
+			vrc4173_cmuclkmsk &= ~MSKAC97;
+			break;
+		case VRC4173_USBU_48MHz_CLOCK:
+			set_cmusrst(USBRST);
+			vrc4173_cmuclkmsk &= ~MSK48MUSB;
+			break;
+		case VRC4173_EXT_48MHz_CLOCK:
+			vrc4173_cmuclkmsk &= ~MSK48MPIN;
+			break;
+		case VRC4173_48MHz_CLOCK:
+			vrc4173_cmuclkmsk &= ~MSK48MOSC;
+			break;
+		default:
+			printk(KERN_WARNING "vrc4173_mask_clock: Invalid CLOCK value %u\n", clock);
+			break;
+		}
+
 		vrc4173_outw(vrc4173_cmuclkmsk, VRC4173_CMUCLKMSK);
+
+		switch (clock) {
+		case VRC4173_USBU_PCI_CLOCK:
+		case VRC4173_USBU_48MHz_CLOCK:
+			clear_cmusrst(USBRST);
+			break;
+		case VRC4173_CARDU1_PCI_CLOCK:
+			clear_cmusrst(CARD1RST);
+			break;
+		case VRC4173_CARDU2_PCI_CLOCK:
+			clear_cmusrst(CARD2RST);
+			break;
+		case VRC4173_AC97U_PCI_CLOCK:
+			clear_cmusrst(AC97RST);
+			break;
+		default:
+			break;
+		}
+
+		spin_unlock_irq(&vrc4173_cmu_lock);
 	}
 }
 
 static inline void vrc4173_cmu_init(void)
 {
 	vrc4173_cmuclkmsk = vrc4173_inw(VRC4173_CMUCLKMSK);
-}
 
-EXPORT_SYMBOL(vrc4173_clock_supply);
-EXPORT_SYMBOL(vrc4173_clock_mask);
+	spin_lock_init(&vrc4173_cmu_lock);
+}
 
 void vrc4173_select_function(int func)
 {
-	u16 val;
-
 	if (vrc4173_initialized) {
-		val = vrc4173_inw(VRC4173_SELECTREG);
+		spin_lock_irq(&vrc4173_giu_lock);
+
 		switch(func) {
 		case PS2CH1_SELECT:
-			val |= 0x0004;
+			vrc4173_selectreg |= 0x0004;
 			break;
 		case PS2CH2_SELECT:
-			val |= 0x0002;
+			vrc4173_selectreg |= 0x0002;
 			break;
 		case TOUCHPANEL_SELECT:
-			val &= 0x0007;
+			vrc4173_selectreg &= 0x0007;
 			break;
 		case KIU8_SELECT:
-			val &= 0x000e;
+			vrc4173_selectreg &= 0x000e;
 			break;
 		case KIU10_SELECT:
-			val &= 0x000c;
+			vrc4173_selectreg &= 0x000c;
 			break;
 		case KIU12_SELECT:
-			val &= 0x0008;
+			vrc4173_selectreg &= 0x0008;
 			break;
 		case GPIO_SELECT:
-			val |= 0x0008;
+			vrc4173_selectreg |= 0x0008;
 			break;
 		}
-		vrc4173_outw(val, VRC4173_SELECTREG);
+
+		vrc4173_outw(vrc4173_selectreg, VRC4173_SELECTREG);
+
+		spin_unlock_irq(&vrc4173_giu_lock);
 	}
 }
 
-EXPORT_SYMBOL(vrc4173_select_function);
+static inline void vrc4173_giu_init(void)
+{
+	vrc4173_selectreg = vrc4173_inw(VRC4173_SELECTREG);
+
+	spin_lock_init(&vrc4173_giu_lock);
+}
 
 static void enable_vrc4173_irq(unsigned int irq)
 {
-	u16 val;
+	uint16_t val;
 
 	val = vrc4173_inw(VRC4173_MSYSINT1REG);
-	val |= (u16)1 << (irq - VRC4173_IRQ_BASE);
+	val |= (uint16_t)1 << (irq - VRC4173_IRQ_BASE);
 	vrc4173_outw(val, VRC4173_MSYSINT1REG);
 }
 
 static void disable_vrc4173_irq(unsigned int irq)
 {
-	u16 val;
+	uint16_t val;
 
 	val = vrc4173_inw(VRC4173_MSYSINT1REG);
-	val &= ~((u16)1 << (irq - VRC4173_IRQ_BASE));
+	val &= ~((uint16_t)1 << (irq - VRC4173_IRQ_BASE));
 	vrc4173_outw(val, VRC4173_MSYSINT1REG);
 }
 
@@ -158,19 +331,18 @@ static void end_vrc4173_irq(unsigned int
 }
 
 static struct hw_interrupt_type vrc4173_irq_type = {
-	"VRC4173",
-	startup_vrc4173_irq,
-	shutdown_vrc4173_irq,
-	enable_vrc4173_irq,
-	disable_vrc4173_irq,
-	ack_vrc4173_irq,
-	end_vrc4173_irq,
-	NULL
+	.typename	= "VRC4173",
+	.startup	= startup_vrc4173_irq,
+	.shutdown	= shutdown_vrc4173_irq,
+	.enable		= enable_vrc4173_irq,
+	.disable	= disable_vrc4173_irq,
+	.ack		= ack_vrc4173_irq,
+	.end		= end_vrc4173_irq,
 };
 
 static int vrc4173_get_irq_number(int irq)
 {
-	u16 status, mask;
+	uint16_t status, mask;
 	int i;
 
         status = vrc4173_inw(VRC4173_SYSINT1REG);
@@ -180,18 +352,18 @@ static int vrc4173_get_irq_number(int ir
 	if (status) {
 		for (i = 0; i < 16; i++)
 			if (status & (0x0001 << i))
-				return VRC4173_IRQ_BASE + i;
+				return VRC4173_IRQ(i);
 	}
 
 	return -EINVAL;
 }
 
-static inline void vrc4173_icu_init(int cascade_irq)
+static inline int vrc4173_icu_init(int cascade_irq)
 {
 	int i;
 
 	if (cascade_irq < GIU_IRQ(0) || cascade_irq > GIU_IRQ(15))
-		return;
+		return -EINVAL;
 	
 	vrc4173_outw(0, VRC4173_MSYSINT1REG);
 
@@ -200,33 +372,38 @@ static inline void vrc4173_icu_init(int 
 
 	for (i = VRC4173_IRQ_BASE; i <= VRC4173_IRQ_LAST; i++)
                 irq_desc[i].handler = &vrc4173_irq_type;
+
+	return 0;
 }
 
-static int __devinit vrc4173_probe(struct pci_dev *pdev,
-                                   const struct pci_device_id *ent)
+static int __devinit vrc4173_probe(struct pci_dev *dev,
+                                   const struct pci_device_id *id)
 {
 	unsigned long start, flags;
 	int err;
 
-	if ((err = pci_enable_device(pdev)) < 0) {
-		printk(KERN_ERR "vrc4173: failed to enable device -- err=%d\n", err);
+	err = pci_enable_device(dev);
+	if (err < 0) {
+		printk(KERN_ERR "vrc4173: Failed to enable PCI device, aborting\n");
 		return err;
 	}
 
-	pci_set_master(pdev);
+	pci_set_master(dev);
 
-	start = pci_resource_start(pdev, 0);
-	if (!start) {
-		printk(KERN_ERR "vrc4173:No PCI I/O resources, aborting\n");
-		return -ENODEV;
+	start = pci_resource_start(dev, 0);
+	if (start == 0) {
+		printk(KERN_ERR "vrc4173:No such PCI I/O resource, aborting\n");
+		return -ENXIO;
 	}
 
-	if (!start || (((flags = pci_resource_flags(pdev, 0)) & IORESOURCE_IO) == 0)) {
-		printk(KERN_ERR "vrc4173: No PCI I/O resources, aborting\n");
-		return -ENODEV;
+	flags = pci_resource_flags(dev, 0);
+	if ((flags & IORESOURCE_IO) == 0) {
+		printk(KERN_ERR "vrc4173: No such PCI I/O resource, aborting\n");
+		return -ENXIO;
 	}
 
-	if ((err = pci_request_regions(pdev, "NEC VRC4173")) < 0) {
+	err = pci_request_regions(dev, "NEC VRC4173");
+	if (err < 0) {
 		printk(KERN_ERR "vrc4173: PCI resources are busy, aborting\n");
 		return err;
 	}
@@ -234,33 +411,46 @@ static int __devinit vrc4173_probe(struc
 	set_vrc4173_io_offset(start);
 
 	vrc4173_cmu_init();
+	vrc4173_giu_init();
 
-	vrc4173_icu_init(pdev->irq);
+	err = vrc4173_icu_init(dev->irq);
+	if (err < 0) {
+		printk(KERN_ERR "vrc4173: Invalid IRQ %d, aborting\n", dev->irq);
+		return err;
+	}
 
-	if ((err = vr41xx_cascade_irq(pdev->irq, vrc4173_get_irq_number)) < 0) {
-		printk(KERN_ERR
-		       "vrc4173: IRQ resource %d is busy, aborting\n", pdev->irq);
+	err = vr41xx_cascade_irq(dev->irq, vrc4173_get_irq_number);
+	if (err < 0) {
+		printk(KERN_ERR "vrc4173: IRQ resource %d is busy, aborting\n", dev->irq);
 		return err;
 	}
 
 	printk(KERN_INFO
-	       "NEC VRC4173 at 0x%#08lx, IRQ is cascaded to %d\n", start, pdev->irq);
+	       "NEC VRC4173 at 0x%#08lx, IRQ is cascaded to %d\n", start, dev->irq);
 
 	return 0;
 }
 
+static void vrc4173_remove(struct pci_dev *dev)
+{
+	free_irq(dev->irq, NULL);
+
+	pci_release_regions(dev);
+}
+
 static struct pci_driver vrc4173_driver = {
-	name:		"NEC VRC4173",
-	probe:		vrc4173_probe,
-	remove:		NULL,
-	id_table:	vrc4173_table,
+	.name		= "NEC VRC4173",
+	.probe		= vrc4173_probe,
+	.remove		= vrc4173_remove,
+	.id_table	= vrc4173_table,
 };
 
 static int __devinit vrc4173_init(void)
 {
 	int err;
 
-	if ((err = pci_module_init(&vrc4173_driver)) < 0)
+	err = pci_module_init(&vrc4173_driver);
+	if (err < 0)
 		return err;
 
 	vrc4173_initialized = 1;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/vr41xx/ibm-workpad/ide-workpad.c linux-2.4.29-pre3/arch/mips/vr41xx/ibm-workpad/ide-workpad.c
--- linux-2.4.28/arch/mips/vr41xx/ibm-workpad/ide-workpad.c	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/vr41xx/ibm-workpad/ide-workpad.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,98 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * IDE routines for typical pc-like standard configurations for the IBM WorkPad z50.
- *
- * Copyright (C) 1998, 1999, 2001 by Ralf Baechle
- */
-/*
- * Changes:
- *  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>  Sun, 24 Feb 2002
- *  - Added IBM WorkPad z50 support.
- */
-#include <linux/sched.h>
-#include <linux/ide.h>
-#include <linux/ioport.h>
-#include <linux/hdreg.h>
-#include <asm/ptrace.h>
-#include <asm/hdreg.h>
-
-static int workpad_ide_default_irq(ide_ioreg_t base)
-{
-	return 49;
-}
-
-static ide_ioreg_t workpad_ide_default_io_base(int index)
-{
-	switch (index) {
-		case 0: return 0x1f0;
-		case 1: return 0x170;
-		case 2: return 0x1e8;
-		case 3: return 0x168;
-		case 4: return 0x1e0;
-		case 5: return 0x160;
-	}
-	return 0;
-}
-
-static void workpad_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port,
-                                        ide_ioreg_t ctrl_port, int *irq)
-{
-	ide_ioreg_t reg = data_port;
-	int i;
-
-	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
-		hw->io_ports[i] = reg;
-		reg += 1;
-	}
-	if (ctrl_port) {
-		hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
-	} else {
-		hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206;
-	}
-	if (irq != NULL)
-		*irq = 0;
-	hw->io_ports[IDE_IRQ_OFFSET] = 0;
-}
-
-static int workpad_ide_request_irq(unsigned int irq,
-                                   void (*handler)(int,void *, struct pt_regs *),
-                                   unsigned long flags, const char *device,
-                                   void *dev_id)
-{
-	return request_irq(irq, handler, SA_SHIRQ, device, dev_id);
-}			
-
-static void workpad_ide_free_irq(unsigned int irq, void *dev_id)
-{
-	free_irq(irq, dev_id);
-}
-
-static int workpad_ide_check_region(ide_ioreg_t from, unsigned int extent)
-{
-	return check_region(from, extent);
-}
-
-static void workpad_ide_request_region(ide_ioreg_t from, unsigned int extent,
-                                       const char *name)
-{
-	request_region(from, extent, name);
-}
-
-static void workpad_ide_release_region(ide_ioreg_t from, unsigned int extent)
-{
-	release_region(from, extent);
-}
-
-struct ide_ops workpad_ide_ops = {
-	&workpad_ide_default_irq,
-	&workpad_ide_default_io_base,
-	&workpad_ide_init_hwif_ports,
-	&workpad_ide_request_irq,
-	&workpad_ide_free_irq,
-	&workpad_ide_check_region,
-	&workpad_ide_request_region,
-	&workpad_ide_release_region
-};
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/vr41xx/ibm-workpad/setup.c linux-2.4.29-pre3/arch/mips/vr41xx/ibm-workpad/setup.c
--- linux-2.4.28/arch/mips/vr41xx/ibm-workpad/setup.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/vr41xx/ibm-workpad/setup.c	2004-12-22 16:07:04.425503776 +0000
@@ -1,33 +1,31 @@
 /*
- * FILE NAME
- *	arch/mips/vr41xx/workpad/setup.c
+ *  setup.c, Setup for the IBM WorkPad z50.
  *
- * BRIEF MODULE DESCRIPTION
- *	Setup for the IBM WorkPad z50.
+ *  Copyright (C) 2002-2004  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
  *
- * Copyright 2002 Yoichi Yuasa
- *                yuasa@hh.iij4u.or.jp
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
  *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms of the GNU General Public License as published by the
- *  Free Software Foundation; either version 2 of the License, or (at your
- *  option) any later version.
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <linux/config.h>
-#include <linux/init.h>
 #include <linux/console.h>
 #include <linux/ide.h>
+#include <linux/init.h>
 #include <linux/ioport.h>
 
-#include <asm/reboot.h>
 #include <asm/time.h>
 #include <asm/vr41xx/workpad.h>
 
-#ifdef CONFIG_BLK_DEV_INITRD
-extern unsigned long initrd_start, initrd_end;
-extern void * __rd_start, * __rd_end;
-#endif
-
 void __init ibm_workpad_setup(void)
 {
 	set_io_port_base(IO_PORT_BASE);
@@ -36,16 +34,6 @@ void __init ibm_workpad_setup(void)
 	iomem_resource.start = IO_MEM_RESOURCE_START;
 	iomem_resource.end = IO_MEM_RESOURCE_END;
 
-#ifdef CONFIG_BLK_DEV_INITRD
-	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
-	initrd_start = (unsigned long)&__rd_start;
-	initrd_end = (unsigned long)&__rd_end;
-#endif
-
-	_machine_restart = vr41xx_restart;
-	_machine_halt = vr41xx_halt;
-	_machine_power_off = vr41xx_power_off;
-
 	board_time_init = vr41xx_time_init;
 	board_timer_setup = vr41xx_timer_setup;
 
@@ -58,8 +46,10 @@ void __init ibm_workpad_setup(void)
 #endif
 
 	vr41xx_bcu_init();
-
 	vr41xx_cmu_init();
+	vr41xx_pmu_init();
 
+#ifdef CONFIG_SERIAL
 	vr41xx_siu_init(SIU_RS232C, 0);
+#endif
 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/vr41xx/nec-eagle/ide-eagle.c linux-2.4.29-pre3/arch/mips/vr41xx/nec-eagle/ide-eagle.c
--- linux-2.4.28/arch/mips/vr41xx/nec-eagle/ide-eagle.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/vr41xx/nec-eagle/ide-eagle.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,96 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * IDE routines for typical pc-like standard configurations
- * for the NEC Eagle/Hawk board.
- *
- * Copyright (C) 1998, 1999, 2001 by Ralf Baechle
- */
-/*
- * Changes:
- *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
- *  Fri,  5 Apr 2002
- *  - Added support for NEC Hawk.
- *
- *  MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
- *  Fri,  1 Mar 2002
- *  - Added support for NEC Eagle.
- */
-#include <linux/sched.h>
-#include <linux/ide.h>
-#include <linux/ioport.h>
-#include <linux/hdreg.h>
-#include <asm/ptrace.h>
-#include <asm/hdreg.h>
-
-static int eagle_ide_default_irq(ide_ioreg_t base)
-{
-	return 0;
-}
-
-static ide_ioreg_t eagle_ide_default_io_base(int index)
-{
-	return 0;
-}
-
-static void eagle_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port,
-                                      ide_ioreg_t ctrl_port, int *irq)
-{
-	ide_ioreg_t reg = data_port;
-	int i;
-
-	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
-		hw->io_ports[i] = reg;
-		reg += 1;
-	}
-	if (ctrl_port) {
-		hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
-	} else {
-		hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206;
-	}
-	if (irq != NULL)
-		*irq = 0;
-	hw->io_ports[IDE_IRQ_OFFSET] = 0;
-}
-
-static int eagle_ide_request_irq(unsigned int irq,
-                                 void (*handler)(int,void *, struct pt_regs *),
-                                 unsigned long flags, const char *device,
-                                 void *dev_id)
-{
-	return request_irq(irq, handler, SA_SHIRQ, device, dev_id);
-}
-
-static void eagle_ide_free_irq(unsigned int irq, void *dev_id)
-{
-	free_irq(irq, dev_id);
-}
-
-static int eagle_ide_check_region(ide_ioreg_t from, unsigned int extent)
-{
-	return check_region(from, extent);
-}
-
-static void eagle_ide_request_region(ide_ioreg_t from, unsigned int extent,
-                                     const char *name)
-{
-	request_region(from, extent, name);
-}
-
-static void eagle_ide_release_region(ide_ioreg_t from, unsigned int extent)
-{
-	release_region(from, extent);
-}
-
-struct ide_ops eagle_ide_ops = {
-	&eagle_ide_default_irq,
-	&eagle_ide_default_io_base,
-	&eagle_ide_init_hwif_ports,
-	&eagle_ide_request_irq,
-	&eagle_ide_free_irq,
-	&eagle_ide_check_region,
-	&eagle_ide_request_region,
-	&eagle_ide_release_region
-};
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/vr41xx/nec-eagle/setup.c linux-2.4.29-pre3/arch/mips/vr41xx/nec-eagle/setup.c
--- linux-2.4.28/arch/mips/vr41xx/nec-eagle/setup.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/vr41xx/nec-eagle/setup.c	2004-12-22 16:07:34.062998192 +0000
@@ -1,34 +1,14 @@
 /*
- * FILE NAME
- *	arch/mips/vr41xx/nec-eagle/setup.c
+ * arch/mips/vr41xx/nec-eagle/setup.c
  *
- * BRIEF MODULE DESCRIPTION
- *	Setup for the NEC Eagle/Hawk board.
+ * Setup for the NEC Eagle/Hawk board.
  *
- * Author: Yoichi Yuasa
- *         yyuasa@mvista.com or source@mvista.com
+ * Author: Yoichi Yuasa <yyuasa@mvista.com, or source@mvista.com>
  *
- * Copyright 2001,2002 MontaVista Software Inc.
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms of the GNU General Public License as published by the
- *  Free Software Foundation; either version 2 of the License, or (at your
- *  option) any later version.
- *
- *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
+ * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 /*
  * Changes:
@@ -40,21 +20,15 @@
  *  - New creation, NEC Eagle is supported.
  */
 #include <linux/config.h>
-#include <linux/init.h>
 #include <linux/console.h>
 #include <linux/ide.h>
+#include <linux/init.h>
 #include <linux/ioport.h>
 
 #include <asm/pci_channel.h>
-#include <asm/reboot.h>
 #include <asm/time.h>
 #include <asm/vr41xx/eagle.h>
 
-#ifdef CONFIG_BLK_DEV_INITRD
-extern unsigned long initrd_start, initrd_end;
-extern void * __rd_start, * __rd_end;
-#endif
-
 extern void eagle_irq_init(void);
 
 #ifdef CONFIG_PCI
@@ -75,8 +49,6 @@ static struct resource vr41xx_pci_mem_re
 	IORESOURCE_MEM
 };
 
-extern struct pci_ops vr41xx_pci_ops;
-
 struct pci_channel mips_pci_channels[] = {
 	{&vr41xx_pci_ops, &vr41xx_pci_io_resource, &vr41xx_pci_mem_resource, 0, 256},
 	{NULL, NULL, NULL, 0, 0}
@@ -115,16 +87,6 @@ void __init nec_eagle_setup(void)
 	iomem_resource.start = IO_MEM1_RESOURCE_START;
 	iomem_resource.end = IO_MEM2_RESOURCE_END;
 
-#ifdef CONFIG_BLK_DEV_INITRD
-	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
-	initrd_start = (unsigned long)&__rd_start;
-	initrd_end = (unsigned long)&__rd_end;
-#endif
-
-	_machine_restart = vr41xx_restart;
-	_machine_halt = vr41xx_halt;
-	_machine_power_off = vr41xx_power_off;
-
 	board_time_init = vr41xx_time_init;
 	board_timer_setup = vr41xx_timer_setup;
 
@@ -139,8 +101,8 @@ void __init nec_eagle_setup(void)
 #endif
 
 	vr41xx_bcu_init();
-
 	vr41xx_cmu_init();
+	vr41xx_pmu_init();
 
 #ifdef CONFIG_SERIAL
 	vr41xx_dsiu_init();
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/vr41xx/tanbac-tb0226/setup.c linux-2.4.29-pre3/arch/mips/vr41xx/tanbac-tb0226/setup.c
--- linux-2.4.28/arch/mips/vr41xx/tanbac-tb0226/setup.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/vr41xx/tanbac-tb0226/setup.c	2004-12-22 16:07:15.971748480 +0000
@@ -1,33 +1,31 @@
 /*
- * FILE NAME
- *	arch/mips/vr41xx/tanbac-tb0226/setup.c
+ *  setup.c, Setup for the TANBAC TB0226.
  *
- * BRIEF MODULE DESCRIPTION
- *	Setup for the TANBAC TB0226.
+ *  Copyright (C) 2002-2004  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
  *
- * Copyright 2002,2003 Yoichi Yuasa
- *                yuasa@hh.iij4u.or.jp
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
  *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms of the GNU General Public License as published by the
- *  Free Software Foundation; either version 2 of the License, or (at your
- *  option) any later version.
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <linux/config.h>
-#include <linux/init.h>
 #include <linux/console.h>
+#include <linux/init.h>
 #include <linux/ioport.h>
 
 #include <asm/pci_channel.h>
-#include <asm/reboot.h>
 #include <asm/time.h>
 #include <asm/vr41xx/tb0226.h>
 
-#ifdef CONFIG_BLK_DEV_INITRD
-extern unsigned long initrd_start, initrd_end;
-extern void * __rd_start, * __rd_end;
-#endif
-
 #ifdef CONFIG_PCI
 static struct resource vr41xx_pci_io_resource = {
 	"PCI I/O space",
@@ -43,8 +41,6 @@ static struct resource vr41xx_pci_mem_re
 	IORESOURCE_MEM
 };
 
-extern struct pci_ops vr41xx_pci_ops;
-
 struct pci_channel mips_pci_channels[] = {
 	{&vr41xx_pci_ops, &vr41xx_pci_io_resource, &vr41xx_pci_mem_resource, 0, 256},
 	{NULL, NULL, NULL, 0, 0}
@@ -83,16 +79,6 @@ void __init tanbac_tb0226_setup(void)
 	iomem_resource.start = IO_MEM1_RESOURCE_START;
 	iomem_resource.end = IO_MEM2_RESOURCE_END;
 
-#ifdef CONFIG_BLK_DEV_INITRD
-	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
-	initrd_start = (unsigned long)&__rd_start;
-	initrd_end = (unsigned long)&__rd_end;
-#endif
-
-	_machine_restart = vr41xx_restart;
-	_machine_halt = vr41xx_halt;
-	_machine_power_off = vr41xx_power_off;
-
 	board_time_init = vr41xx_time_init;
 	board_timer_setup = vr41xx_timer_setup;
 
@@ -101,10 +87,12 @@ void __init tanbac_tb0226_setup(void)
 #endif
 
 	vr41xx_bcu_init();
-
 	vr41xx_cmu_init();
+	vr41xx_pmu_init();
 
+#ifdef CONFIG_SERIAL
 	vr41xx_siu_init(SIU_RS232C, 0);
+#endif
 
 #ifdef CONFIG_PCI
 	vr41xx_pciu_init(&pci_address_map);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/vr41xx/tanbac-tb0229/Makefile linux-2.4.29-pre3/arch/mips/vr41xx/tanbac-tb0229/Makefile
--- linux-2.4.28/arch/mips/vr41xx/tanbac-tb0229/Makefile	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/vr41xx/tanbac-tb0229/Makefile	2004-12-22 16:07:55.263775184 +0000
@@ -12,8 +12,9 @@ O_TARGET := tb0229.o
 
 all: tb0229.o
 
-obj-y	:= init.o setup.o reboot.o
+obj-y	:= init.o setup.o
 
-obj-$(CONFIG_PCI)	+= pci_fixup.o
+obj-$(CONFIG_PCI)		+= pci_fixup.o
+obj-$(CONFIG_TANBAC_TB0219)	+= reboot.o
 
 include $(TOPDIR)/Rules.make
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/vr41xx/tanbac-tb0229/reboot.c linux-2.4.29-pre3/arch/mips/vr41xx/tanbac-tb0229/reboot.c
--- linux-2.4.28/arch/mips/vr41xx/tanbac-tb0229/reboot.c	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/vr41xx/tanbac-tb0229/reboot.c	2004-12-22 16:06:21.304059232 +0000
@@ -16,15 +16,11 @@
 #include <asm/io.h>
 #include <asm/vr41xx/tb0229.h>
 
-#define tb0229_hard_reset()	writew(0, TB0219_RESET_REGS)
+#define tb0219_hard_reset()	writew(0, TB0219_RESET_REGS)
 
-void tanbac_tb0229_restart(char *command)
+void tanbac_tb0219_restart(char *command)
 {
-#ifdef CONFIG_TANBAC_TB0219
 	local_irq_disable();
-	tb0229_hard_reset();
+	tb0219_hard_reset();
 	while (1);
-#else
-	vr41xx_restart(command);
-#endif
 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/vr41xx/tanbac-tb0229/setup.c linux-2.4.29-pre3/arch/mips/vr41xx/tanbac-tb0229/setup.c
--- linux-2.4.28/arch/mips/vr41xx/tanbac-tb0229/setup.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/vr41xx/tanbac-tb0229/setup.c	2004-12-22 16:06:38.601429632 +0000
@@ -1,24 +1,26 @@
 /*
- * FILE NAME
- *	arch/mips/vr41xx/tanbac-tb0229/setup.c
+ *  setup.c, Setup for the TANBAC TB0229 (VR4131DIMM)
  *
- * BRIEF MODULE DESCRIPTION
- *	Setup for the TANBAC TB0229 (VR4131DIMM)
+ *  Copyright (C) 2002-2004  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
  *
- * Copyright 2002,2003 Yoichi Yuasa
- *                yuasa@hh.iij4u.or.jp
+ *  Modified for TANBAC TB0229:
+ *  Copyright (C) 2003 Megasolution Inc.  <matsu@megasolution.jp>
  *
- * Modified for TANBAC TB0229:
- * Copyright 2003 Megasolution Inc.
- *                matsu@megasolution.jp
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
  *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms of the GNU General Public License as published by the
- *  Free Software Foundation; either version 2 of the License, or (at your
- *  option) any later version.
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <linux/config.h>
-#include <linux/blk.h>
 #include <linux/console.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
@@ -28,10 +30,6 @@
 #include <asm/time.h>
 #include <asm/vr41xx/tb0229.h>
 
-#ifdef CONFIG_BLK_DEV_INITRD
-extern void * __rd_start, * __rd_end;
-#endif
-
 #ifdef CONFIG_PCI
 static struct resource vr41xx_pci_io_resource = {
 	.name	= "PCI I/O space",
@@ -47,8 +45,6 @@ static struct resource vr41xx_pci_mem_re
 	.flags	= IORESOURCE_MEM,
 };
 
-extern struct pci_ops vr41xx_pci_ops;
-
 struct pci_channel mips_pci_channels[] = {
 	{	.pci_ops	= &vr41xx_pci_ops,
 		.io_resource	= &vr41xx_pci_io_resource,
@@ -95,16 +91,6 @@ void __init tanbac_tb0229_setup(void)
 	iomem_resource.start = IO_MEM1_RESOURCE_START;
 	iomem_resource.end = IO_MEM2_RESOURCE_END;
 
-#ifdef CONFIG_BLK_DEV_INITRD
-	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
-	initrd_start = (unsigned long)&__rd_start;
-	initrd_end = (unsigned long)&__rd_end;
-#endif
-
-	_machine_restart = tanbac_tb0229_restart;
-	_machine_halt = vr41xx_halt;
-	_machine_power_off = vr41xx_power_off;
-
 	board_time_init = vr41xx_time_init;
 	board_timer_setup = vr41xx_timer_setup;
 
@@ -113,14 +99,19 @@ void __init tanbac_tb0229_setup(void)
 #endif
 
 	vr41xx_bcu_init();
-
 	vr41xx_cmu_init();
+	vr41xx_pmu_init();
 
+#ifdef CONFIG_SERIAL
 	vr41xx_siu_init(SIU_RS232C, 0);
 	vr41xx_dsiu_init();
+#endif
 
 #ifdef CONFIG_PCI
 	vr41xx_pciu_init(&pci_address_map);
 #endif
-}
 
+#ifdef CONFIG_TANBAC_TB0219
+	_machine_restart = tanbac_tb0219_restart;
+#endif
+}
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/vr41xx/victor-mpc30x/ide-mpc30x.c linux-2.4.29-pre3/arch/mips/vr41xx/victor-mpc30x/ide-mpc30x.c
--- linux-2.4.28/arch/mips/vr41xx/victor-mpc30x/ide-mpc30x.c	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/vr41xx/victor-mpc30x/ide-mpc30x.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,91 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * IDE routines for typical pc-like standard configurations
- * for the ZAO Networks Capcella.
- *
- * Copyright (C) 1998, 1999, 2001 by Ralf Baechle
- */
-/*
- * Changes:
- *  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>  Fri, 23 Aug 2002
- *  - Added Victor MP-C303/304 support.
- */
-#include <linux/sched.h>
-#include <linux/ide.h>
-#include <linux/ioport.h>
-#include <linux/hdreg.h>
-#include <asm/ptrace.h>
-#include <asm/hdreg.h>
-
-static int mpc30x_ide_default_irq(ide_ioreg_t base)
-{
-	return 0;
-}
-
-static ide_ioreg_t mpc30x_ide_default_io_base(int index)
-{
-	return 0;
-}
-
-static void mpc30x_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port,
-                                       ide_ioreg_t ctrl_port, int *irq)
-{
-	ide_ioreg_t reg = data_port;
-	int i;
-
-	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
-		hw->io_ports[i] = reg;
-		reg += 1;
-	}
-	if (ctrl_port) {
-		hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
-	} else {
-		hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206;
-	}
-	if (irq != NULL)
-		*irq = 0;
-	hw->io_ports[IDE_IRQ_OFFSET] = 0;
-}
-
-static int mpc30x_ide_request_irq(unsigned int irq,
-                                  void (*handler)(int,void *, struct pt_regs *),
-                                  unsigned long flags, const char *device,
-                                  void *dev_id)
-{
-	return request_irq(irq, handler, flags, device, dev_id);
-}
-
-static void mpc30x_ide_free_irq(unsigned int irq, void *dev_id)
-{
-	free_irq(irq, dev_id);
-}
-
-static int mpc30x_ide_check_region(ide_ioreg_t from, unsigned int extent)
-{
-	return check_region(from, extent);
-}
-
-static void mpc30x_ide_request_region(ide_ioreg_t from, unsigned int extent,
-                                      const char *name)
-{
-	request_region(from, extent, name);
-}
-
-static void mpc30x_ide_release_region(ide_ioreg_t from, unsigned int extent)
-{
-	release_region(from, extent);
-}
-
-struct ide_ops mpc30x_ide_ops = {
-	&mpc30x_ide_default_irq,
-	&mpc30x_ide_default_io_base,
-	&mpc30x_ide_init_hwif_ports,
-	&mpc30x_ide_request_irq,
-	&mpc30x_ide_free_irq,
-	&mpc30x_ide_check_region,
-	&mpc30x_ide_request_region,
-	&mpc30x_ide_release_region
-};
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/vr41xx/victor-mpc30x/setup.c linux-2.4.29-pre3/arch/mips/vr41xx/victor-mpc30x/setup.c
--- linux-2.4.28/arch/mips/vr41xx/victor-mpc30x/setup.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/vr41xx/victor-mpc30x/setup.c	2004-12-22 16:07:54.993816224 +0000
@@ -1,34 +1,32 @@
 /*
- * FILE NAME
- *	arch/mips/vr41xx/victor-mpc30x/setup.c
+ *  setup.c, Setup for the Victor MP-C303/304.
  *
- * BRIEF MODULE DESCRIPTION
- *	Setup for the Victor MP-C303/304.
+ *  Copyright (C) 2002-2004  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
  *
- * Copyright 2002 Yoichi Yuasa
- *                yuasa@hh.iij4u.or.jp
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
  *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms of the GNU General Public License as published by the
- *  Free Software Foundation; either version 2 of the License, or (at your
- *  option) any later version.
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <linux/config.h>
-#include <linux/init.h>
 #include <linux/console.h>
 #include <linux/ide.h>
+#include <linux/init.h>
 #include <linux/ioport.h>
 
 #include <asm/pci_channel.h>
-#include <asm/reboot.h>
 #include <asm/time.h>
 #include <asm/vr41xx/mpc30x.h>
 
-#ifdef CONFIG_BLK_DEV_INITRD
-extern unsigned long initrd_start, initrd_end;
-extern void * __rd_start, * __rd_end;
-#endif
-
 #ifdef CONFIG_PCI
 static struct resource vr41xx_pci_io_resource = {
 	"PCI I/O space",
@@ -44,8 +42,6 @@ static struct resource vr41xx_pci_mem_re
 	IORESOURCE_MEM
 };
 
-extern struct pci_ops vr41xx_pci_ops;
-
 struct pci_channel mips_pci_channels[] = {
 	{&vr41xx_pci_ops, &vr41xx_pci_io_resource, &vr41xx_pci_mem_resource, 0, 256},
 	{NULL, NULL, NULL, 0, 0}
@@ -84,16 +80,6 @@ void __init victor_mpc30x_setup(void)
 	iomem_resource.start = IO_MEM1_RESOURCE_START;
 	iomem_resource.end = IO_MEM2_RESOURCE_END;
 
-#ifdef CONFIG_BLK_DEV_INITRD
-	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
-	initrd_start = (unsigned long)&__rd_start;
-	initrd_end = (unsigned long)&__rd_end;
-#endif
-
-	_machine_restart = vr41xx_restart;
-	_machine_halt = vr41xx_halt;
-	_machine_power_off = vr41xx_power_off;
-
 	board_time_init = vr41xx_time_init;
 	board_timer_setup = vr41xx_timer_setup;
 
@@ -106,10 +92,12 @@ void __init victor_mpc30x_setup(void)
 #endif
 
 	vr41xx_bcu_init();
-
 	vr41xx_cmu_init();
+	vr41xx_pmu_init();
 
+#ifdef CONFIG_SERIAL
 	vr41xx_siu_init(SIU_RS232C, 0);
+#endif
 
 #ifdef CONFIG_PCI
 	vr41xx_pciu_init(&pci_address_map);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/vr41xx/zao-capcella/ide-capcella.c linux-2.4.29-pre3/arch/mips/vr41xx/zao-capcella/ide-capcella.c
--- linux-2.4.28/arch/mips/vr41xx/zao-capcella/ide-capcella.c	2002-11-28 23:53:10.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/vr41xx/zao-capcella/ide-capcella.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,99 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * IDE routines for typical pc-like standard configurations
- * for the ZAO Networks Capcella.
- *
- * Copyright (C) 1998, 1999, 2001 by Ralf Baechle
- */
-/*
- * Changes:
- *  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>  Sun, 24 Feb 2002
- *  - Added ZAO Networks Capcella support.
- */
-#include <linux/sched.h>
-#include <linux/ide.h>
-#include <linux/ioport.h>
-#include <linux/hdreg.h>
-#include <asm/ptrace.h>
-#include <asm/hdreg.h>
-
-static int capcella_ide_default_irq(ide_ioreg_t base)
-{
-	switch (base) {
-	case 0x8300: return 42;
-	}
-
-	return 0;
-}
-
-static ide_ioreg_t capcella_ide_default_io_base(int index)
-{
-	switch (index) {
-	case 0: return 0x8300;
-	}
-
-	return 0;
-}
-
-static void capcella_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port,
-                                         ide_ioreg_t ctrl_port, int *irq)
-{
-	ide_ioreg_t reg = data_port;
-	int i;
-
-	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
-		hw->io_ports[i] = reg;
-		reg += 1;
-	}
-	if (ctrl_port) {
-		hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
-	} else {
-		hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206;
-	}
-	if (irq != NULL)
-		*irq = 0;
-	hw->io_ports[IDE_IRQ_OFFSET] = 0;
-}
-
-static int capcella_ide_request_irq(unsigned int irq,
-                                    void (*handler)(int,void *, struct pt_regs *),
-                                    unsigned long flags, const char *device,
-                                    void *dev_id)
-{
-	return request_irq(irq, handler, flags, device, dev_id);
-}
-
-static void capcella_ide_free_irq(unsigned int irq, void *dev_id)
-{
-	free_irq(irq, dev_id);
-}
-
-static int capcella_ide_check_region(ide_ioreg_t from, unsigned int extent)
-{
-	return check_region(from, extent);
-}
-
-static void capcella_ide_request_region(ide_ioreg_t from, unsigned int extent,
-                                        const char *name)
-{
-	request_region(from, extent, name);
-}
-
-static void capcella_ide_release_region(ide_ioreg_t from, unsigned int extent)
-{
-	release_region(from, extent);
-}
-
-struct ide_ops capcella_ide_ops = {
-	&capcella_ide_default_irq,
-	&capcella_ide_default_io_base,
-	&capcella_ide_init_hwif_ports,
-	&capcella_ide_request_irq,
-	&capcella_ide_free_irq,
-	&capcella_ide_check_region,
-	&capcella_ide_request_region,
-	&capcella_ide_release_region
-};
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips/vr41xx/zao-capcella/setup.c linux-2.4.29-pre3/arch/mips/vr41xx/zao-capcella/setup.c
--- linux-2.4.28/arch/mips/vr41xx/zao-capcella/setup.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips/vr41xx/zao-capcella/setup.c	2004-12-22 16:07:40.977946960 +0000
@@ -1,34 +1,32 @@
 /*
- * FILE NAME
- *	arch/mips/vr41xx/zao-capcella/setup.c
+ *  setup.c, Setup for the ZAO Networks Capcella.
  *
- * BRIEF MODULE DESCRIPTION
- *	Setup for the ZAO Networks Capcella.
+ *  Copyright (C) 2002-2004  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
  *
- * Copyright 2002 Yoichi Yuasa
- *                yuasa@hh.iij4u.or.jp
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
  *
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms of the GNU General Public License as published by the
- *  Free Software Foundation; either version 2 of the License, or (at your
- *  option) any later version.
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <linux/config.h>
-#include <linux/init.h>
 #include <linux/console.h>
 #include <linux/ide.h>
+#include <linux/init.h>
 #include <linux/ioport.h>
 
 #include <asm/pci_channel.h>
-#include <asm/reboot.h>
 #include <asm/time.h>
 #include <asm/vr41xx/capcella.h>
 
-#ifdef CONFIG_BLK_DEV_INITRD
-extern unsigned long initrd_start, initrd_end;
-extern void * __rd_start, * __rd_end;
-#endif
-
 #ifdef CONFIG_PCI
 static struct resource vr41xx_pci_io_resource = {
 	"PCI I/O space",
@@ -44,8 +42,6 @@ static struct resource vr41xx_pci_mem_re
 	IORESOURCE_MEM
 };
 
-extern struct pci_ops vr41xx_pci_ops;
-
 struct pci_channel mips_pci_channels[] = {
 	{&vr41xx_pci_ops, &vr41xx_pci_io_resource, &vr41xx_pci_mem_resource, 0, 256},
 	{NULL, NULL, NULL, 0, 0}
@@ -84,16 +80,6 @@ void __init zao_capcella_setup(void)
 	iomem_resource.start = IO_MEM1_RESOURCE_START;
 	iomem_resource.end = IO_MEM2_RESOURCE_END;
 
-#ifdef CONFIG_BLK_DEV_INITRD
-	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
-	initrd_start = (unsigned long)&__rd_start;
-	initrd_end = (unsigned long)&__rd_end;
-#endif
-
-	_machine_restart = vr41xx_restart;
-	_machine_halt = vr41xx_halt;
-	_machine_power_off = vr41xx_power_off;
-
 	board_time_init = vr41xx_time_init;
 	board_timer_setup = vr41xx_timer_setup;
 
@@ -106,11 +92,13 @@ void __init zao_capcella_setup(void)
 #endif
 
 	vr41xx_bcu_init();
-
 	vr41xx_cmu_init();
+	vr41xx_pmu_init();
 
+#ifdef CONFIG_SERIAL
 	vr41xx_siu_init(SIU_RS232C, 0);
 	vr41xx_dsiu_init();
+#endif
 
 #ifdef CONFIG_PCI
 	vr41xx_pciu_init(&pci_address_map);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/Makefile linux-2.4.29-pre3/arch/mips64/Makefile
--- linux-2.4.28/arch/mips64/Makefile	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/Makefile	2004-12-22 16:06:03.118823808 +0000
@@ -3,7 +3,7 @@
 # License.  See the file "COPYING" in the main directory of this archive
 # for more details.
 #
-# Copyright (C) 2002, 2003  Maciej W. Rozycki
+# Copyright (C) 2002, 2003, 2004  Maciej W. Rozycki
 #
 # This file is included by the global makefile so that you can add your own
 # architecture-specific flags and dependencies. Remember to do have actions
@@ -26,6 +26,9 @@ ifdef CONFIG_CROSSCOMPILE
 CROSS_COMPILE	= $(tool-prefix)
 endif
 
+check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi)
+check_gas = $(shell if $(CC) $(1) -Wa,-Z -c -o /dev/null -xassembler /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi)
+
 #
 # The ELF GCC uses -G 0 -mabicalls -fpic as default.  We don't need PIC
 # code in the kernel since it only slows down the whole thing.  For the
@@ -37,9 +40,9 @@ endif
 # crossformat linking we rely on the elf2ecoff tool for format conversion.
 #
 GCCFLAGS	:= -I $(TOPDIR)/include/asm/gcc
-GCCFLAGS	+= -mabi=64 -G 0 -mno-abicalls -fno-pic -Wa,--trap -pipe
+GCCFLAGS	+= -G 0 -mno-abicalls -fno-pic -Wa,--trap -pipe
 GCCFLAGS	+= $(call check_gcc, -finline-limit=100000,)
-LINKFLAGS	+= -G 0 -static # -N
+LINKFLAGS	+= -G 0 -static -n
 MODFLAGS	+= -mlong-calls
 
 ifdef CONFIG_DEBUG_INFO
@@ -49,9 +52,6 @@ GCCFLAGS	+= -mno-sched-prolog -fno-omit-
 endif
 endif
 
-check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi)
-check_gas = $(shell if $(CC) $(1) -Wa,-Z -c -o /dev/null -xassembler /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi)
-
 #
 # Use: $(call set_gccflags,<cpu0>,<isa0>,<cpu1>,<isa1>)
 #
@@ -76,6 +76,7 @@ while :; do \
 	done; \
 	break; \
 done; \
+gcc_abi=-mabi=64; \
 gcc_cpu=$$cpu; gcc_isa=$$isa; \
 gas_cpu=$$cpu; gas_isa=-Wa,$$isa; \
 while :; do \
@@ -87,7 +88,12 @@ while :; do \
 	gas_opt=; gas_cpu=; gas_isa=; \
 	break; \
 done; \
-echo $$gcc_opt$$gcc_cpu $$gcc_isa $$gas_opt$$gas_cpu $$gas_isa)
+if test "$$gcc_opt" = -march=; then \
+	$(CC) $$gcc_abi $$gcc_opt$$gcc_cpu -S -o /dev/null \
+		-xc /dev/null > /dev/null 2>&1 && \
+		gcc_isa=; \
+fi; \
+echo $$gcc_abi $$gcc_opt$$gcc_cpu $$gcc_isa $$gas_opt$$gas_cpu $$gas_isa)
 
 #
 # CPU-dependent compiler/assembler options for optimization.
@@ -154,7 +160,7 @@ endif
 ifdef CONFIG_MIPS_COBALT
 SUBDIRS		+= arch/mips/cobalt
 CORE_FILES	+= arch/mips/cobalt/cobalt.o
-LOADADDR	:= 0x80080000
+LOADADDR	:= 0xffffffff80080000
 endif
 
 #
@@ -164,7 +170,7 @@ ifdef CONFIG_DECSTATION
 CORE_FILES	+= arch/mips/dec/dec.o
 SUBDIRS		+= arch/mips/dec arch/mips/dec/prom
 LIBS		+= arch/mips/dec/prom/rexlib.a
-LOADADDR	:= 0x80040000
+LOADADDR	:= 0xffffffff80040000
 endif
 
 #
@@ -174,7 +180,7 @@ ifdef CONFIG_MIPS_EV64120
 LIBS		+= arch/mips/gt64120/common/gt64120.o \
 		   arch/mips/gt64120/ev64120/ev64120.o
 SUBDIRS		+= arch/mips/gt64120/common arch/mips/gt64120/ev64120
-LOADADDR	:= 0x80100000
+LOADADDR	:= 0xffffffff80100000
 endif
 
 #
@@ -184,7 +190,7 @@ ifdef CONFIG_MIPS_ATLAS
 LIBS		+= arch/mips/mips-boards/atlas/atlas.o \
 		   arch/mips/mips-boards/generic/mipsboards.o
 SUBDIRS		+= arch/mips/mips-boards/generic arch/mips/mips-boards/atlas
-LOADADDR	:= 0x80100000
+LOADADDR	:= 0xffffffff80100000
 endif
 
 #
@@ -194,7 +200,7 @@ ifdef CONFIG_MIPS_MALTA
 LIBS		+= arch/mips/mips-boards/malta/malta.o \
 		   arch/mips/mips-boards/generic/mipsboards.o
 SUBDIRS		+= arch/mips/mips-boards/malta arch/mips/mips-boards/generic
-LOADADDR	:= 0x80100000
+LOADADDR	:= 0xffffffff80100000
 endif
 
 #
@@ -204,7 +210,7 @@ ifdef CONFIG_MIPS_SEAD
 LIBS		+= arch/mips/mips-boards/sead/sead.o \
 		   arch/mips/mips-boards/generic/mipsboards.o
 SUBDIRS		+= arch/mips/mips-boards/generic arch/mips/mips-boards/sead
-LOADADDR	:= 0x80100000
+LOADADDR	:= 0xffffffff80100000
 endif
 
 #
@@ -216,7 +222,7 @@ ifdef CONFIG_MOMENCO_OCELOT
 CORE_FILES      += arch/mips/gt64120/common/gt64120.o \
 		   arch/mips/gt64120/momenco_ocelot/momenco_ocelot.o
 SUBDIRS		+= arch/mips/gt64120/common arch/mips/gt64120/momenco_ocelot
-LOADADDR	:= 0x80100000
+LOADADDR	:= 0xffffffff80100000
 endif
 
 #
@@ -227,7 +233,7 @@ ifdef CONFIG_MOMENCO_OCELOT_G
 # mips_io_port_base.
 CORE_FILES	+= arch/mips/momentum/ocelot_g/ocelot_g.o
 SUBDIRS		+= arch/mips/momentum/ocelot_g
-LOADADDR	:= 0x80100000
+LOADADDR	:= 0xffffffff80100000
 endif
                                                                                 
 #
@@ -236,16 +242,16 @@ endif
 ifdef CONFIG_MOMENCO_OCELOT_C
 CORE_FILES	+= arch/mips/momentum/ocelot_c/ocelot_c.o
 SUBDIRS		+= arch/mips/momentum/ocelot_c
-LOADADDR	:= 0x80100000
+LOADADDR	:= 0xffffffff80100000
 endif
 
 ifdef CONFIG_MOMENCO_JAGUAR_ATX
 LIBS		+= arch/mips/momentum/jaguar_atx/jaguar_atx.o
 SUBDIRS		+= arch/mips/momentum/jaguar_atx
 ifdef CONFIG_JAGUAR_DMALOW
-LOADADDR	:= 0x88000000
+LOADADDR	:= 0xffffffff88000000
 else
-LOADADDR	:= 0x80100000
+LOADADDR	:= 0xffffffff80100000
 endif
 endif
 
@@ -262,11 +268,11 @@ CORE_FILES	+= arch/mips/sgi-ip22/ip22-ke
 LIBS		+= arch/mips/arc/arclib.a
 SUBDIRS		+= arch/mips/sgi-ip22 arch/mips/arc
 #
-# Set LOADADDR to >= 0x88069000 if you want to leave space for symmon,
-# 0x88004000 for production kernels.  Note that the value must be
+# Set LOADADDR to >= 0xffffffff88069000 if you want to leave space for symmon,
+# 0xffffffff88004000 for production kernels.  Note that the value must be
 # 16kb aligned or the handling of the current variable will break.
 #
-LOADADDR	:= 0x88004000
+LOADADDR	:= 0xffffffff88004000
 endif
 
 #
@@ -281,11 +287,22 @@ SUBDIRS		+= arch/mips/sgi-ip27 arch/mips
 # symmon, 0xc00000000001c000 for production kernels.  Note that the value
 # must be 16kb aligned or the handling of the current variable will break.
 #
-#LOADADDR	:= 0xa80000000001c000
+ifdef CONFIG_BUILD_ELF64
+ifdef CONFIG_MAPPED_KERNEL
+LOADADDR	:= 0xc00000004001c000
+OBJCOPYFLAGS	:= --change-addresses=0x3fffffff80000000
+else
+LOADADDR	:= 0xa80000000001c000
+OBJCOPYFLAGS	:= --change-addresses=0x57ffffff80000000
+endif
+else
 ifdef CONFIG_MAPPED_KERNEL
-LOADADDR	:= 0xc001c000
+LOADADDR	:= 0xffffffffc001c000
+OBJCOPYFLAGS	:= --change-addresses=0xc000000080000000
 else
-LOADADDR	:= 0x8001c000
+LOADADDR	:= 0xffffffff8001c000
+OBJCOPYFLAGS	:= --change-addresses=0xa800000080000000
+endif
 endif
 endif
 
@@ -299,9 +316,9 @@ ifneq ($(CONFIG_SIBYTE_SB1250)$(CONFIG_S
 LIBS		+= arch/mips/sibyte/sb1250/sb1250.o
 SUBDIRS		+= arch/mips/sibyte/sb1250
 ifdef CONFIG_MIPS_UNCACHED
-LOADADDR	:= 0xa0100000
+LOADADDR	:= 0xffffffffa0100000
 else
-LOADADDR	:= 0x80100000
+LOADADDR	:= 0xffffffff80100000
 endif
 endif
 
@@ -328,43 +345,43 @@ LIBS		+= arch/mips/sibyte/cfe/cfe.a
 SUBDIRS		+= arch/mips/sibyte/cfe
 endif
 
-#
-# Some machines like the Indy need 32-bit ELF binaries for booting purposes.
-# Other need ECOFF, so we build a 32-bit ELF binary for them which we then
-# convert to ECOFF using elf2ecoff.
-#
-ifdef CONFIG_BOOT_ELF32
-GCCFLAGS += -Wa,-32 $(call check_gas,-Wa$(comma)-mgp64,)
-LINKFLAGS += -T arch/mips64/ld.script.elf32
-endif
-#
-# The 64-bit ELF tools are pretty broken so at this time we generate 64-bit
-# ELF files from 32-bit files by conversion.
-#
-ifdef CONFIG_BOOT_ELF64
-GCCFLAGS += -Wa,-32 $(call check_gas,-Wa$(comma)-mgp64,)
-LINKFLAGS += -T arch/mips64/ld.script.elf32
-#AS += -64
-#LD += -m elf64bmip
-#LINKFLAGS += -T arch/mips64/ld.script.elf64
-endif
 
 ifdef CONFIG_CPU_LITTLE_ENDIAN
 32bit-bfd = elf32-tradlittlemips
 64bit-bfd = elf64-tradlittlemips
+32bit-emul = elf32ltsmip
+64bit-emul = elf64ltsmip
 else
 32bit-bfd = elf32-tradbigmips
 64bit-bfd = elf64-tradbigmips
+32bit-emul = elf32btsmip
+64bit-emul = elf64btsmip
+endif
+
+ifdef CONFIG_BUILD_ELF64
+GCCFLAGS += -Wa,-64
+LOADSCRIPT = arch/mips64/ld.script.elf64
+ld-emul = $(64bit-emul)
+vmlinux-32 = vmlinux.32
+vmlinux-64 = vmlinux
+else
+GCCFLAGS += $(call check_gcc,-mno-explicit-relocs,)
+GCCFLAGS += -Wa,-32 $(call check_gas,-Wa$(comma)-mgp64,)
+LOADSCRIPT = arch/mips64/ld.script.elf32
+ld-emul = $(32bit-emul)
+vmlinux-32 = vmlinux
+vmlinux-64 = vmlinux.64
 endif
 
 
 AFLAGS		+= $(GCCFLAGS)
 CFLAGS		+= $(GCCFLAGS)
 
-LD		+= --oformat $(32bit-bfd)
+LD		+= -m $(ld-emul)
 
 
-LINKFLAGS += -Ttext $(LOADADDR)
+LINKFLAGS += -T $(LOADSCRIPT) -Ttext $(LOADADDR)
+OBJCOPYFLAGS += --remove-section=.reginfo
 
 HEAD := arch/mips64/kernel/head.o arch/mips64/kernel/init_task.o
 
@@ -372,27 +389,51 @@ SUBDIRS := $(addprefix arch/mips/, tools
 CORE_FILES := arch/mips64/kernel/kernel.o arch/mips64/mm/mm.o $(CORE_FILES)
 LIBS := arch/mips64/lib/lib.a $(LIBS)
 
-MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot VMLINUX=$(TOPDIR)/$(vmlinux-32)
 
-vmlinux: arch/mips64/ld.script.elf32
 arch/mips64/ld.script.elf32: arch/mips64/ld.script.elf32.S
 	$(CPP) -C -P -I$(HPATH) -imacros $(HPATH)/asm-mips64/sn/mapped_kernel.h -Umips arch/mips64/ld.script.elf32.S > arch/mips64/ld.script.elf32
 
-ifdef CONFIG_MAPPED_KERNEL
-vmlinux.64: vmlinux
-	$(OBJCOPY) -O $(64bit-bfd) --remove-section=.reginfo --change-addresses=0xc000000080000000 $< $@
-else
+vmlinux: $(LOADSCRIPT)
+
+#
+# Some machines like the Indy need 32-bit ELF binaries for booting purposes.
+# Other need ECOFF, so we build a 32-bit ELF binary for them which we then
+# convert to ECOFF using elf2ecoff.
+#
+vmlinux.32: vmlinux
+	$(OBJCOPY) -O $(32bit-bfd) $(OBJCOPYFLAGS) $< $@
+
+#
+# The 64-bit ELF tools are pretty broken so at this time we generate 64-bit
+# ELF files from 32-bit files by conversion.
+#
 vmlinux.64: vmlinux
-	$(OBJCOPY) -O $(64bit-bfd) --remove-section=.reginfo --change-addresses=0xa800000080000000 $< $@
+	$(OBJCOPY) -O $(64bit-bfd) $(OBJCOPYFLAGS) $< $@
+
+ifdef CONFIG_BOOT_ELF32
+boot: $(vmlinux-32)
 endif
 
-vmlinux.ecoff: vmlinux
+ifdef CONFIG_BOOT_ELF64
+boot: $(vmlinux-64)
+endif
+
+boot: mips-boot
+
+mips-boot: $(vmlinux-32)
+	@$(MAKEBOOT) boot
+
+vmlinux.ecoff: $(vmlinux-32)
+	@$(MAKEBOOT) $@
+
+vmlinux.srec: $(vmlinux-32)
 	@$(MAKEBOOT) $@
 
 archclean:
 	@$(MAKEBOOT) clean
 	$(MAKE) -C arch/mips/tools clean
-	rm -f vmlinux.64 arch/$(ARCH)/ld.script.elf32
+	rm -f vmlinux.32 vmlinux.64 arch/$(ARCH)/ld.script.elf32
 
 archmrproper:
 	@$(MAKEBOOT) mrproper
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/boot/Makefile linux-2.4.29-pre3/arch/mips64/boot/Makefile
--- linux-2.4.28/arch/mips64/boot/Makefile	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/boot/Makefile	2004-12-22 16:07:37.471480024 +0000
@@ -4,6 +4,7 @@
 # for more details.
 #
 # Copyright (C) 1995, 1998, 1999 by Ralf Baechle
+# Copyright (C) 2004  Maciej W. Rozycki
 #
 
 USE_STANDARD_AS_RULE := true
@@ -17,14 +18,28 @@ else
   E2EFLAGS =
 endif
 
-all: vmlinux.ecoff addinitrd
+#
+# Drop some uninteresting sections in the kernel.
+# This is only relevant for ELF kernels but doesn't hurt a.out
+#
+drop-sections	= .reginfo .mdebug .comment .note .pdr .options .MIPS.options
+strip-flags	= $(addprefix --remove-section=,$(drop-sections))
+
+VMLINUX = $(TOPDIR)/vmlinux
 
-vmlinux.ecoff:	$(CONFIGURE) elf2ecoff $(TOPDIR)/vmlinux
-	./elf2ecoff $(TOPDIR)/vmlinux vmlinux.ecoff $(E2EFLAGS)
+all:
+
+boot: vmlinux.ecoff vmlinux.srec addinitrd
+
+vmlinux.ecoff: $(CONFIGURE) elf2ecoff $(VMLINUX)
+	./elf2ecoff $(VMLINUX) vmlinux.ecoff $(E2EFLAGS)
 
 elf2ecoff: $(TOPDIR)/arch/mips/boot/elf2ecoff.c
 	$(HOSTCC) -I$(TOPDIR)/arch/mips/boot -I- -o $@ $^
 
+vmlinux.srec: $(CONFIGURE) $(VMLINUX)
+	$(OBJCOPY) -S -O srec $(strip-flags) $(VMLINUX) vmlinux.srec
+
 addinitrd: $(TOPDIR)/arch/mips/boot/addinitrd.c
 	$(HOSTCC) -I$(TOPDIR)/arch/mips/boot -I- -o $@ $^
 
@@ -32,10 +47,10 @@ addinitrd: $(TOPDIR)/arch/mips/boot/addi
 dep:
 
 clean:
-	rm -f vmlinux.ecoff
+	rm -f vmlinux.ecoff vmlinux.srec
 
 mrproper:
-	rm -f vmlinux.ecoff addinitrd elf2ecoff
+	rm -f vmlinux.ecoff vmlinux.srec addinitrd elf2ecoff
 
 dummy:
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/defconfig linux-2.4.29-pre3/arch/mips64/defconfig
--- linux-2.4.28/arch/mips64/defconfig	2004-12-22 16:17:15.649583592 +0000
+++ linux-2.4.29-pre3/arch/mips64/defconfig	2004-12-22 16:05:58.099586848 +0000
@@ -8,12 +8,14 @@ CONFIG_MIPS64=y
 #
 # Code maturity level options
 #
-# CONFIG_EXPERIMENTAL is not set
+CONFIG_EXPERIMENTAL=y
 
 #
 # Loadable module support
 #
-# CONFIG_MODULES is not set
+CONFIG_MODULES=y
+CONFIG_MODVERSIONS=y
+CONFIG_KMOD=y
 
 #
 # Machine selection
@@ -24,10 +26,12 @@ CONFIG_MIPS64=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -50,6 +54,8 @@ CONFIG_MIPS64=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -81,8 +87,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_BOOT_ELF64=y
 CONFIG_ARC64=y
 CONFIG_L1_CACHE_SHIFT=7
-CONFIG_NEW_TIME_C=y
-CONFIG_PCI=y
 CONFIG_QL_ISP_A64=y
 # CONFIG_MIPS_AU1000 is not set
 
@@ -107,6 +111,8 @@ CONFIG_CPU_R10000=y
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
 CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_SMP=y
 # CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
@@ -119,9 +125,13 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BUILD_ELF64 is not set
 # CONFIG_BINFMT_IRIX is not set
 # CONFIG_MIPS_INSANE_LARGE is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+# CONFIG_PCI_NEW is not set
+CONFIG_PCI_AUTO=y
 CONFIG_PCI_NAMES=y
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -143,6 +153,7 @@ CONFIG_MIPS32_O32=y
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -172,6 +183,7 @@ CONFIG_BINFMT_ELF32=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -196,8 +208,9 @@ CONFIG_BINFMT_ELF32=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_NETLINK_DEV=y
-# CONFIG_NETFILTER is not set
-# CONFIG_FILTER is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_FILTER=y
 CONFIG_UNIX=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -206,35 +219,199 @@ CONFIG_IP_PNP=y
 # CONFIG_IP_PNP_DHCP is not set
 # CONFIG_IP_PNP_BOOTP is not set
 # CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_INET_ECN 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_INET_ECN=y
 # CONFIG_SYN_COOKIES is not set
-# CONFIG_VLAN_8021Q is not set
+
+#
+#   IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=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_UNCLEAN is not set
+# CONFIG_IP_NF_MATCH_OWNER is not set
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+# CONFIG_IP_NF_TARGET_MIRROR is not set
+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_NAT_AMANDA=m
+CONFIG_IP_NF_NAT_LOCAL=y
+# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=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_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=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_COMPAT_IPFWADM=m
+CONFIG_IP_NF_NAT_NEEDED=y
+
+#
+#   IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# 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
+
+#
+#   IPv6: Netfilter Configuration
+#
+CONFIG_IP6_NF_QUEUE=m
+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_KHTTPD is not set
+
+#
+#    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_VLAN_8021Q=m
 
 #
 #  
 #
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
 
 #
 # Appletalk devices
 #
-# CONFIG_DEV_APPLETALK is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
+CONFIG_DEV_APPLETALK=y
+# CONFIG_COPS_DAYNA is not set
+# CONFIG_COPS_TANGENT is not set
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+CONFIG_DECNET=m
+CONFIG_DECNET_SIOCGIFCONF=y
+CONFIG_DECNET_ROUTER=y
+CONFIG_DECNET_ROUTE_FWMARK=y
+CONFIG_BRIDGE=m
+CONFIG_X25=m
+CONFIG_LAPB=m
+# CONFIG_LLC is not set
+CONFIG_NET_DIVERT=y
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
 
 #
 # QoS and/or fair queueing
 #
-# CONFIG_NET_SCHED is not set
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_CSZ=m
+CONFIG_NET_SCH_HFSC=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_NETEM is not set
+CONFIG_NET_SCH_DSMARK=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 is not set
 
 #
 # Network testing
 #
-# CONFIG_NET_PKTGEN is not set
+CONFIG_NET_PKTGEN=m
 
 #
 # Telephony Support
@@ -259,10 +436,12 @@ CONFIG_SCSI=y
 #
 CONFIG_BLK_DEV_SD=y
 CONFIG_SD_EXTRA_DEVS=40
-CONFIG_CHR_DEV_ST=y
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_CHR_DEV_SG is not set
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_SR_EXTRA_DEVS=4
+CONFIG_CHR_DEV_SG=m
 
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -281,6 +460,7 @@ CONFIG_SCSI_LOGGING=y
 # CONFIG_SCSI_AHA152X is not set
 # CONFIG_SCSI_AHA1542 is not set
 # CONFIG_SCSI_AHA1740 is not set
+# CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
@@ -290,6 +470,17 @@ CONFIG_SCSI_LOGGING=y
 # CONFIG_SCSI_AM53C974 is not set
 # CONFIG_SCSI_MEGARAID is not set
 # CONFIG_SCSI_MEGARAID2 is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_SATA_SVW is not set
+# CONFIG_SCSI_ATA_PIIX is not set
+# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SCSI_SATA_PROMISE is not set
+# CONFIG_SCSI_SATA_SX4 is not set
+# CONFIG_SCSI_SATA_SIL is not set
+# CONFIG_SCSI_SATA_SIS is not set
+# CONFIG_SCSI_SATA_ULI is not set
+# CONFIG_SCSI_SATA_VIA is not set
+# CONFIG_SCSI_SATA_VITESSE is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_CPQFCTS is not set
 # CONFIG_SCSI_DMX3191D is not set
@@ -321,6 +512,7 @@ CONFIG_SCSI_QLOGIC_ISP=y
 # CONFIG_SCSI_T128 is not set
 # CONFIG_SCSI_U14_34F is not set
 # CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
 
 #
 # Fusion MPT device support
@@ -332,6 +524,11 @@ CONFIG_SCSI_QLOGIC_ISP=y
 # CONFIG_FUSION_LAN is not set
 
 #
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
 # Network device support
 #
 CONFIG_NETDEVICES=y
@@ -344,6 +541,7 @@ CONFIG_NETDEVICES=y
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -378,6 +576,7 @@ CONFIG_SGI_IOC3_ETH=y
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
 # CONFIG_PLIP is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -392,6 +591,8 @@ CONFIG_SGI_IOC3_ETH=y
 #
 # CONFIG_TR is not set
 # CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
 
 #
 # Wan interfaces
@@ -401,7 +602,34 @@ CONFIG_SGI_IOC3_ETH=y
 #
 # Amateur Radio support
 #
-# CONFIG_HAMRADIO is not set
+CONFIG_HAMRADIO=y
+
+#
+# Packet Radio protocols
+#
+CONFIG_AX25=m
+CONFIG_AX25_DAMA_SLAVE=y
+CONFIG_NETROM=m
+CONFIG_ROSE=m
+
+#
+# AX.25 network device drivers
+#
+
+#
+# AX.25 network device drivers
+#
+CONFIG_MKISS=m
+CONFIG_6PACK=m
+CONFIG_BPQETHER=m
+# CONFIG_SCC_DELAY is not set
+# CONFIG_SCC_TRXECHO is not set
+# CONFIG_BAYCOM_SER_FDX is not set
+# CONFIG_BAYCOM_SER_HDX is not set
+# CONFIG_BAYCOM_PAR is not set
+# CONFIG_BAYCOM_EPP is not set
+# CONFIG_SOUNDMODEM is not set
+# CONFIG_YAM is not set
 
 #
 # IrDA (infrared) support
@@ -431,6 +659,7 @@ CONFIG_SERIAL=y
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -473,8 +702,7 @@ CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
-CONFIG_SGI_IP27_RTC=y
+CONFIG_SGI_IP27_RTC=m
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -493,11 +721,11 @@ CONFIG_SGI_IP27_RTC=y
 #
 # File systems
 #
-# CONFIG_QUOTA is not set
-# CONFIG_QFMT_V2 is not set
+CONFIG_QUOTA=y
+CONFIG_QFMT_V2=y
 CONFIG_AUTOFS_FS=y
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_REISERFS_FS is not set
+CONFIG_AUTOFS4_FS=m
+CONFIG_REISERFS_FS=m
 # CONFIG_REISERFS_CHECK is not set
 # CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_ADFS_FS is not set
@@ -511,43 +739,43 @@ CONFIG_AUTOFS_FS=y
 CONFIG_EXT3_FS=y
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
-# CONFIG_FAT_FS is not set
-# CONFIG_MSDOS_FS is not set
-# CONFIG_UMSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_UMSDOS_FS=m
+CONFIG_VFAT_FS=m
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_JFFS2_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_TMPFS is not set
+CONFIG_CRAMFS=m
+CONFIG_TMPFS=y
 CONFIG_RAMFS=y
-# CONFIG_ISO9660_FS is not set
-# CONFIG_JOLIET is not set
-# CONFIG_ZISOFS is not set
-# CONFIG_JFS_FS is not set
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_JFS_FS=m
 # CONFIG_JFS_DEBUG is not set
 # CONFIG_JFS_STATISTICS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_NTFS_FS is not set
+CONFIG_MINIX_FS=m
+CONFIG_VXFS_FS=m
+CONFIG_NTFS_FS=m
 # CONFIG_NTFS_RW is not set
-# CONFIG_HPFS_FS is not set
+CONFIG_HPFS_FS=m
 CONFIG_PROC_FS=y
 # CONFIG_DEVFS_FS is not set
 # CONFIG_DEVFS_MOUNT is not set
 # CONFIG_DEVFS_DEBUG is not set
 CONFIG_DEVPTS_FS=y
-# CONFIG_QNX4FS_FS is not set
+CONFIG_QNX4FS_FS=m
 # CONFIG_QNX4FS_RW is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=y
-# CONFIG_SYSV_FS is not set
-# CONFIG_UDF_FS is not set
+CONFIG_ROMFS_FS=m
+CONFIG_EXT2_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UDF_FS=m
 # CONFIG_UDF_RW is not set
-# CONFIG_UFS_FS is not set
+CONFIG_UFS_FS=m
 # CONFIG_UFS_FS_WRITE is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_XFS_QUOTA is not set
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
 # CONFIG_XFS_RT is not set
 # CONFIG_XFS_TRACE is not set
 # CONFIG_XFS_DEBUG is not set
@@ -561,23 +789,25 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_DIRECTIO is not set
 CONFIG_ROOT_NFS=y
-# CONFIG_NFSD is not set
-# CONFIG_NFSD_V3 is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
 CONFIG_NFSD_TCP=y
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
-# CONFIG_SMB_FS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
-# CONFIG_ZISOFS_FS is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+CONFIG_SMB_UNIX=y
+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_ZISOFS_FS=m
 
 #
 # Partition Types
@@ -598,8 +828,50 @@ CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
-# CONFIG_SMB_NLS is not set
-# CONFIG_NLS is not set
+CONFIG_SMB_NLS=y
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+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
 
 #
 # Multimedia devices
@@ -647,5 +919,5 @@ CONFIG_LOG_BUF_SHIFT=0
 # Library routines
 #
 # CONFIG_CRC32 is not set
-# CONFIG_ZLIB_INFLATE is not set
+CONFIG_ZLIB_INFLATE=m
 # CONFIG_ZLIB_DEFLATE is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/defconfig-atlas linux-2.4.29-pre3/arch/mips64/defconfig-atlas
--- linux-2.4.28/arch/mips64/defconfig-atlas	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/defconfig-atlas	2004-12-22 16:05:43.186853928 +0000
@@ -24,10 +24,12 @@ CONFIG_EXPERIMENTAL=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -50,6 +52,8 @@ CONFIG_MIPS_ATLAS=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -76,9 +80,7 @@ CONFIG_L1_CACHE_SHIFT=5
 CONFIG_MIPS_BONITO64=y
 CONFIG_MIPS_GT64120=y
 CONFIG_MIPS_MSC=y
-CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
-CONFIG_PCI=y
 CONFIG_SWAP_IO_SPACE_W=y
 CONFIG_SWAP_IO_SPACE_L=y
 # CONFIG_MIPS_AU1000 is not set
@@ -117,8 +119,12 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BUILD_ELF64 is not set
 # CONFIG_BINFMT_IRIX is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+# CONFIG_PCI_NEW is not set
+# CONFIG_PCI_AUTO is not set
 CONFIG_PCI_NAMES=y
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -140,6 +146,7 @@ CONFIG_MIPS32_O32=y
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -169,6 +176,7 @@ CONFIG_BINFMT_ELF32=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
@@ -215,7 +223,6 @@ CONFIG_IP_PNP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -306,6 +313,17 @@ CONFIG_SD_EXTRA_DEVS=40
 # CONFIG_SCSI_AM53C974 is not set
 # CONFIG_SCSI_MEGARAID is not set
 # CONFIG_SCSI_MEGARAID2 is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_SATA_SVW is not set
+# CONFIG_SCSI_ATA_PIIX is not set
+# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SCSI_SATA_PROMISE is not set
+# CONFIG_SCSI_SATA_SX4 is not set
+# CONFIG_SCSI_SATA_SIL is not set
+# CONFIG_SCSI_SATA_SIS is not set
+# CONFIG_SCSI_SATA_ULI is not set
+# CONFIG_SCSI_SATA_VIA is not set
+# CONFIG_SCSI_SATA_VITESSE is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_CPQFCTS is not set
 # CONFIG_SCSI_DMX3191D is not set
@@ -456,6 +474,7 @@ CONFIG_SERIAL=y
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -498,7 +517,6 @@ CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 CONFIG_RTC=y
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/defconfig-decstation linux-2.4.29-pre3/arch/mips64/defconfig-decstation
--- linux-2.4.28/arch/mips64/defconfig-decstation	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/defconfig-decstation	2004-12-22 16:06:55.059927560 +0000
@@ -24,10 +24,12 @@ CONFIG_EXPERIMENTAL=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -50,6 +52,8 @@ CONFIG_DECSTATION=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -71,10 +75,10 @@ CONFIG_DECSTATION=y
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_EARLY_PRINTK=y
 CONFIG_BOOT_ELF32=y
 CONFIG_IRQ_CPU=y
 CONFIG_L1_CACHE_SHIFT=4
-CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
 # CONFIG_MIPS_AU1000 is not set
 
@@ -112,6 +116,7 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_BUILD_ELF64=y
 CONFIG_NET=y
 # CONFIG_PCI is not set
 # CONFIG_ISA is not set
@@ -134,6 +139,7 @@ CONFIG_MIPS32_O32=y
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -163,6 +169,7 @@ CONFIG_BINFMT_ELF32=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -208,7 +215,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -300,6 +306,17 @@ CONFIG_SCSI_DECNCR=y
 # CONFIG_SCSI_AM53C974 is not set
 # CONFIG_SCSI_MEGARAID is not set
 # CONFIG_SCSI_MEGARAID2 is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_SATA_SVW is not set
+# CONFIG_SCSI_ATA_PIIX is not set
+# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SCSI_SATA_PROMISE is not set
+# CONFIG_SCSI_SATA_SX4 is not set
+# CONFIG_SCSI_SATA_SIL is not set
+# CONFIG_SCSI_SATA_SIS is not set
+# CONFIG_SCSI_SATA_ULI is not set
+# CONFIG_SCSI_SATA_VIA is not set
+# CONFIG_SCSI_SATA_VITESSE is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_DTC3280 is not set
@@ -460,6 +477,7 @@ CONFIG_SERIAL_DEC=y
 CONFIG_SERIAL_DEC_CONSOLE=y
 # CONFIG_DZ is not set
 CONFIG_ZS=y
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -502,7 +520,6 @@ CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/defconfig-ip22 linux-2.4.29-pre3/arch/mips64/defconfig-ip22
--- linux-2.4.28/arch/mips64/defconfig-ip22	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/defconfig-ip22	2004-12-22 16:05:32.369498416 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_KMOD=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -81,7 +85,6 @@ CONFIG_BOOT_ELF32=y
 CONFIG_SWAP_IO_SPACE_L=y
 CONFIG_IRQ_CPU=y
 CONFIG_L1_CACHE_SHIFT=5
-CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_PC_KEYB=y
 # CONFIG_MIPS_AU1000 is not set
@@ -120,11 +123,12 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BUILD_ELF64 is not set
 # CONFIG_BINFMT_IRIX is not set
 CONFIG_ARC_CONSOLE=y
 CONFIG_NET=y
-# CONFIG_EISA is not set
 # CONFIG_PCI is not set
+# CONFIG_EISA is not set
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
 # CONFIG_MCA is not set
@@ -145,6 +149,7 @@ CONFIG_MIPS32_O32=y
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -174,6 +179,7 @@ CONFIG_BINFMT_ELF32=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -220,7 +226,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -313,6 +318,17 @@ CONFIG_SGIWD93_SCSI=y
 # CONFIG_SCSI_AM53C974 is not set
 # CONFIG_SCSI_MEGARAID is not set
 # CONFIG_SCSI_MEGARAID2 is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_SATA_SVW is not set
+# CONFIG_SCSI_ATA_PIIX is not set
+# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SCSI_SATA_PROMISE is not set
+# CONFIG_SCSI_SATA_SX4 is not set
+# CONFIG_SCSI_SATA_SIL is not set
+# CONFIG_SCSI_SATA_SIS is not set
+# CONFIG_SCSI_SATA_ULI is not set
+# CONFIG_SCSI_SATA_VIA is not set
+# CONFIG_SCSI_SATA_VITESSE is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_DTC3280 is not set
@@ -472,6 +488,7 @@ CONFIG_SERIAL_NONSTANDARD=y
 # CONFIG_SERIAL_TXX9_CONSOLE is not set
 # CONFIG_TXX927_SERIAL is not set
 CONFIG_IP22_SERIAL=y
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -534,13 +551,11 @@ CONFIG_WATCHDOG=y
 # CONFIG_WDTPCI is not set
 # CONFIG_MACHZ_WDT is not set
 # CONFIG_INDYDOG is not set
-# CONFIG_AMD7XX_TCO is not set
 # CONFIG_SCx200 is not set
 # CONFIG_SCx200_GPIO is not set
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 CONFIG_DS1286=y
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
@@ -630,7 +645,7 @@ CONFIG_NFS_FS=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
 # CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
+CONFIG_NFSD_TCP=y
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/defconfig-ip27 linux-2.4.29-pre3/arch/mips64/defconfig-ip27
--- linux-2.4.28/arch/mips64/defconfig-ip27	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/defconfig-ip27	2004-12-22 16:06:43.905623272 +0000
@@ -8,12 +8,14 @@ CONFIG_MIPS64=y
 #
 # Code maturity level options
 #
-# CONFIG_EXPERIMENTAL is not set
+CONFIG_EXPERIMENTAL=y
 
 #
 # Loadable module support
 #
-# CONFIG_MODULES is not set
+CONFIG_MODULES=y
+CONFIG_MODVERSIONS=y
+CONFIG_KMOD=y
 
 #
 # Machine selection
@@ -24,10 +26,12 @@ CONFIG_MIPS64=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -50,6 +54,8 @@ CONFIG_MIPS64=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -81,8 +87,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_BOOT_ELF64=y
 CONFIG_ARC64=y
 CONFIG_L1_CACHE_SHIFT=7
-CONFIG_NEW_TIME_C=y
-CONFIG_PCI=y
 CONFIG_QL_ISP_A64=y
 # CONFIG_MIPS_AU1000 is not set
 
@@ -107,6 +111,8 @@ CONFIG_CPU_R10000=y
 # CONFIG_CPU_RM9000 is not set
 # CONFIG_CPU_SB1 is not set
 CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_SMP=y
 # CONFIG_64BIT_PHYS_ADDR is not set
 # CONFIG_CPU_ADVANCED is not set
@@ -119,9 +125,13 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BUILD_ELF64 is not set
 # CONFIG_BINFMT_IRIX is not set
 # CONFIG_MIPS_INSANE_LARGE is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+# CONFIG_PCI_NEW is not set
+CONFIG_PCI_AUTO=y
 CONFIG_PCI_NAMES=y
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -143,6 +153,7 @@ CONFIG_MIPS32_O32=y
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -172,6 +183,7 @@ CONFIG_BINFMT_ELF32=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -196,8 +208,9 @@ CONFIG_BINFMT_ELF32=y
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_NETLINK_DEV=y
-# CONFIG_NETFILTER is not set
-# CONFIG_FILTER is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_FILTER=y
 CONFIG_UNIX=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -206,35 +219,199 @@ CONFIG_IP_PNP=y
 # CONFIG_IP_PNP_DHCP is not set
 # CONFIG_IP_PNP_BOOTP is not set
 # CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_INET_ECN 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_INET_ECN=y
 # CONFIG_SYN_COOKIES is not set
-# CONFIG_VLAN_8021Q is not set
+
+#
+#   IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_IRC=m
+# CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=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_UNCLEAN is not set
+# CONFIG_IP_NF_MATCH_OWNER is not set
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+# CONFIG_IP_NF_TARGET_MIRROR is not set
+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_NAT_AMANDA=m
+CONFIG_IP_NF_NAT_LOCAL=y
+# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=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_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=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_COMPAT_IPFWADM=m
+CONFIG_IP_NF_NAT_NEEDED=y
+
+#
+#   IP: Virtual Server Configuration
+#
+CONFIG_IP_VS=m
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# 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
+
+#
+#   IPv6: Netfilter Configuration
+#
+CONFIG_IP6_NF_QUEUE=m
+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_KHTTPD is not set
+
+#
+#    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_VLAN_8021Q=m
 
 #
 #  
 #
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
+CONFIG_IPX=m
+# CONFIG_IPX_INTERN is not set
+CONFIG_ATALK=m
 
 #
 # Appletalk devices
 #
-# CONFIG_DEV_APPLETALK is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
+CONFIG_DEV_APPLETALK=y
+# CONFIG_COPS_DAYNA is not set
+# CONFIG_COPS_TANGENT is not set
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+CONFIG_DECNET=m
+CONFIG_DECNET_SIOCGIFCONF=y
+CONFIG_DECNET_ROUTER=y
+CONFIG_DECNET_ROUTE_FWMARK=y
+CONFIG_BRIDGE=m
+CONFIG_X25=m
+CONFIG_LAPB=m
+# CONFIG_LLC is not set
+CONFIG_NET_DIVERT=y
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
 
 #
 # QoS and/or fair queueing
 #
-# CONFIG_NET_SCHED is not set
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_CSZ=m
+CONFIG_NET_SCH_HFSC=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_NETEM is not set
+CONFIG_NET_SCH_DSMARK=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 is not set
 
 #
 # Network testing
 #
-# CONFIG_NET_PKTGEN is not set
+CONFIG_NET_PKTGEN=m
 
 #
 # Telephony Support
@@ -259,10 +436,12 @@ CONFIG_SCSI=y
 #
 CONFIG_BLK_DEV_SD=y
 CONFIG_SD_EXTRA_DEVS=40
-CONFIG_CHR_DEV_ST=y
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_CHR_DEV_SG is not set
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_SR_EXTRA_DEVS=4
+CONFIG_CHR_DEV_SG=m
 
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
@@ -281,6 +460,7 @@ CONFIG_SCSI_LOGGING=y
 # CONFIG_SCSI_AHA152X is not set
 # CONFIG_SCSI_AHA1542 is not set
 # CONFIG_SCSI_AHA1740 is not set
+# CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
@@ -290,6 +470,17 @@ CONFIG_SCSI_LOGGING=y
 # CONFIG_SCSI_AM53C974 is not set
 # CONFIG_SCSI_MEGARAID is not set
 # CONFIG_SCSI_MEGARAID2 is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_SATA_SVW is not set
+# CONFIG_SCSI_ATA_PIIX is not set
+# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SCSI_SATA_PROMISE is not set
+# CONFIG_SCSI_SATA_SX4 is not set
+# CONFIG_SCSI_SATA_SIL is not set
+# CONFIG_SCSI_SATA_SIS is not set
+# CONFIG_SCSI_SATA_ULI is not set
+# CONFIG_SCSI_SATA_VIA is not set
+# CONFIG_SCSI_SATA_VITESSE is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_CPQFCTS is not set
 # CONFIG_SCSI_DMX3191D is not set
@@ -321,6 +512,7 @@ CONFIG_SCSI_QLOGIC_ISP=y
 # CONFIG_SCSI_T128 is not set
 # CONFIG_SCSI_U14_34F is not set
 # CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
 
 #
 # Fusion MPT device support
@@ -332,6 +524,11 @@ CONFIG_SCSI_QLOGIC_ISP=y
 # CONFIG_FUSION_LAN is not set
 
 #
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
 # Network device support
 #
 CONFIG_NETDEVICES=y
@@ -344,6 +541,7 @@ CONFIG_NETDEVICES=y
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -378,6 +576,7 @@ CONFIG_SGI_IOC3_ETH=y
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
 # CONFIG_PLIP is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
@@ -392,6 +591,8 @@ CONFIG_SGI_IOC3_ETH=y
 #
 # CONFIG_TR is not set
 # CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
 
 #
 # Wan interfaces
@@ -401,7 +602,34 @@ CONFIG_SGI_IOC3_ETH=y
 #
 # Amateur Radio support
 #
-# CONFIG_HAMRADIO is not set
+CONFIG_HAMRADIO=y
+
+#
+# Packet Radio protocols
+#
+CONFIG_AX25=m
+CONFIG_AX25_DAMA_SLAVE=y
+CONFIG_NETROM=m
+CONFIG_ROSE=m
+
+#
+# AX.25 network device drivers
+#
+
+#
+# AX.25 network device drivers
+#
+CONFIG_MKISS=m
+CONFIG_6PACK=m
+CONFIG_BPQETHER=m
+# CONFIG_SCC_DELAY is not set
+# CONFIG_SCC_TRXECHO is not set
+# CONFIG_BAYCOM_SER_FDX is not set
+# CONFIG_BAYCOM_SER_HDX is not set
+# CONFIG_BAYCOM_PAR is not set
+# CONFIG_BAYCOM_EPP is not set
+# CONFIG_SOUNDMODEM is not set
+# CONFIG_YAM is not set
 
 #
 # IrDA (infrared) support
@@ -431,6 +659,7 @@ CONFIG_SERIAL=y
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -473,8 +702,7 @@ CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
-CONFIG_SGI_IP27_RTC=y
+CONFIG_SGI_IP27_RTC=m
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -493,11 +721,11 @@ CONFIG_SGI_IP27_RTC=y
 #
 # File systems
 #
-# CONFIG_QUOTA is not set
-# CONFIG_QFMT_V2 is not set
+CONFIG_QUOTA=y
+CONFIG_QFMT_V2=y
 CONFIG_AUTOFS_FS=y
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_REISERFS_FS is not set
+CONFIG_AUTOFS4_FS=m
+CONFIG_REISERFS_FS=m
 # CONFIG_REISERFS_CHECK is not set
 # CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_ADFS_FS is not set
@@ -511,43 +739,43 @@ CONFIG_AUTOFS_FS=y
 CONFIG_EXT3_FS=y
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
-# CONFIG_FAT_FS is not set
-# CONFIG_MSDOS_FS is not set
-# CONFIG_UMSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_UMSDOS_FS=m
+CONFIG_VFAT_FS=m
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_JFFS2_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_TMPFS is not set
+CONFIG_CRAMFS=m
+CONFIG_TMPFS=y
 CONFIG_RAMFS=y
-# CONFIG_ISO9660_FS is not set
-# CONFIG_JOLIET is not set
-# CONFIG_ZISOFS is not set
-# CONFIG_JFS_FS is not set
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_JFS_FS=m
 # CONFIG_JFS_DEBUG is not set
 # CONFIG_JFS_STATISTICS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_NTFS_FS is not set
+CONFIG_MINIX_FS=m
+CONFIG_VXFS_FS=m
+CONFIG_NTFS_FS=m
 # CONFIG_NTFS_RW is not set
-# CONFIG_HPFS_FS is not set
+CONFIG_HPFS_FS=m
 CONFIG_PROC_FS=y
 # CONFIG_DEVFS_FS is not set
 # CONFIG_DEVFS_MOUNT is not set
 # CONFIG_DEVFS_DEBUG is not set
 CONFIG_DEVPTS_FS=y
-# CONFIG_QNX4FS_FS is not set
+CONFIG_QNX4FS_FS=m
 # CONFIG_QNX4FS_RW is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=y
-# CONFIG_SYSV_FS is not set
-# CONFIG_UDF_FS is not set
+CONFIG_ROMFS_FS=m
+CONFIG_EXT2_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UDF_FS=m
 # CONFIG_UDF_RW is not set
-# CONFIG_UFS_FS is not set
+CONFIG_UFS_FS=m
 # CONFIG_UFS_FS_WRITE is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_XFS_QUOTA is not set
+CONFIG_XFS_FS=m
+CONFIG_XFS_QUOTA=y
 # CONFIG_XFS_RT is not set
 # CONFIG_XFS_TRACE is not set
 # CONFIG_XFS_DEBUG is not set
@@ -561,23 +789,25 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_DIRECTIO is not set
 CONFIG_ROOT_NFS=y
-# CONFIG_NFSD is not set
-# CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_TCP=y
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
-# CONFIG_SMB_FS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
-# CONFIG_ZISOFS_FS is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+CONFIG_SMB_UNIX=y
+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_ZISOFS_FS=m
 
 #
 # Partition Types
@@ -598,8 +828,50 @@ CONFIG_SGI_PARTITION=y
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
 # CONFIG_EFI_PARTITION is not set
-# CONFIG_SMB_NLS is not set
-# CONFIG_NLS is not set
+CONFIG_SMB_NLS=y
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+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
 
 #
 # Multimedia devices
@@ -647,5 +919,5 @@ CONFIG_LOG_BUF_SHIFT=0
 # Library routines
 #
 # CONFIG_CRC32 is not set
-# CONFIG_ZLIB_INFLATE is not set
+CONFIG_ZLIB_INFLATE=m
 # CONFIG_ZLIB_DEFLATE is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/defconfig-jaguar linux-2.4.29-pre3/arch/mips64/defconfig-jaguar
--- linux-2.4.28/arch/mips64/defconfig-jaguar	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/defconfig-jaguar	2004-12-22 16:07:41.385884944 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_KMOD=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -112,9 +116,12 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BUILD_ELF64 is not set
 # CONFIG_BINFMT_IRIX is not set
 CONFIG_NET=y
 # CONFIG_PCI is not set
+# CONFIG_PCI_NEW is not set
+CONFIG_PCI_AUTO=y
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
 # CONFIG_MCA is not set
@@ -135,6 +142,7 @@ CONFIG_MIPS32_N32=y
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -164,6 +172,7 @@ CONFIG_BINFMT_ELF32=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -209,7 +218,6 @@ CONFIG_IP_PNP_DHCP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -395,6 +403,7 @@ CONFIG_SERIAL_NONSTANDARD=y
 # CONFIG_SERIAL_TXX9 is not set
 # CONFIG_SERIAL_TXX9_CONSOLE is not set
 # CONFIG_TXX927_SERIAL is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/defconfig-malta linux-2.4.29-pre3/arch/mips64/defconfig-malta
--- linux-2.4.28/arch/mips64/defconfig-malta	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/defconfig-malta	2004-12-22 16:06:31.665484056 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_MIPS_MALTA=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -80,12 +84,10 @@ CONFIG_MIPS_BONITO64=y
 CONFIG_MIPS_GT64120=y
 CONFIG_MIPS_MSC=y
 CONFIG_L1_CACHE_SHIFT=5
-CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_SWAP_IO_SPACE_W=y
 CONFIG_SWAP_IO_SPACE_L=y
 CONFIG_PC_KEYB=y
-CONFIG_PCI=y
 # CONFIG_MIPS_AU1000 is not set
 
 #
@@ -122,7 +124,11 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+# CONFIG_PCI_NEW is not set
+# CONFIG_PCI_AUTO is not set
 CONFIG_PCI_NAMES=y
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -144,6 +150,7 @@ CONFIG_MIPS32_O32=y
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -173,6 +180,7 @@ CONFIG_BLK_DEV_FD=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
@@ -218,7 +226,6 @@ CONFIG_IP_PNP_BOOTP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -309,6 +316,17 @@ CONFIG_SD_EXTRA_DEVS=40
 # CONFIG_SCSI_AM53C974 is not set
 # CONFIG_SCSI_MEGARAID is not set
 # CONFIG_SCSI_MEGARAID2 is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_SATA_SVW is not set
+# CONFIG_SCSI_ATA_PIIX is not set
+# CONFIG_SCSI_SATA_NV is not set
+# CONFIG_SCSI_SATA_PROMISE is not set
+# CONFIG_SCSI_SATA_SX4 is not set
+# CONFIG_SCSI_SATA_SIL is not set
+# CONFIG_SCSI_SATA_SIS is not set
+# CONFIG_SCSI_SATA_ULI is not set
+# CONFIG_SCSI_SATA_VIA is not set
+# CONFIG_SCSI_SATA_VITESSE is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_CPQFCTS is not set
 # CONFIG_SCSI_DMX3191D is not set
@@ -459,6 +477,7 @@ CONFIG_SERIAL=y
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -501,7 +520,6 @@ CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 CONFIG_RTC=y
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -590,7 +608,7 @@ CONFIG_NFS_V3=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
-# CONFIG_NFSD_TCP is not set
+CONFIG_NFSD_TCP=y
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/defconfig-ocelotc linux-2.4.29-pre3/arch/mips64/defconfig-ocelotc
--- linux-2.4.28/arch/mips64/defconfig-ocelotc	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/defconfig-ocelotc	2004-12-22 16:06:00.720188456 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_KMOD=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 CONFIG_MOMENCO_OCELOT_C=y
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -73,10 +77,8 @@ CONFIG_MOMENCO_OCELOT_C=y
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-CONFIG_PCI=y
 CONFIG_SWAP_IO_SPACE=y
 CONFIG_NONCOHERENT_IO=y
-CONFIG_NEW_TIME_C=y
 CONFIG_BOOT_ELF32=y
 # CONFIG_MIPS_AU1000 is not set
 
@@ -117,8 +119,12 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
+# CONFIG_BUILD_ELF64 is not set
 # CONFIG_BINFMT_IRIX is not set
 CONFIG_NET=y
+CONFIG_PCI=y
+# CONFIG_PCI_NEW is not set
+CONFIG_PCI_AUTO=y
 # CONFIG_PCI_NAMES is not set
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
@@ -140,6 +146,7 @@ CONFIG_MIPS32_N32=y
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -169,6 +176,7 @@ CONFIG_BINFMT_ELF32=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_NBD=y
 # CONFIG_BLK_DEV_RAM is not set
@@ -214,7 +222,6 @@ CONFIG_IP_PNP_DHCP=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -330,6 +337,7 @@ CONFIG_NET_PCI=y
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
+# CONFIG_FORCEDETH is not set
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
 # CONFIG_8139CP is not set
@@ -445,6 +453,7 @@ CONFIG_SERIAL_NONSTANDARD=y
 # CONFIG_SERIAL_TXX9 is not set
 # CONFIG_SERIAL_TXX9_CONSOLE is not set
 # CONFIG_TXX927_SERIAL is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -487,7 +496,6 @@ CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-CONFIG_MIPS_RTC=y
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/defconfig-sb1250-swarm linux-2.4.29-pre3/arch/mips64/defconfig-sb1250-swarm
--- linux-2.4.28/arch/mips64/defconfig-sb1250-swarm	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/defconfig-sb1250-swarm	2004-12-22 16:05:51.049658600 +0000
@@ -26,10 +26,12 @@ CONFIG_KMOD=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -52,6 +54,8 @@ CONFIG_KMOD=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -84,7 +88,6 @@ CONFIG_SIBYTE_CFE=y
 # CONFIG_SIBYTE_BW_TRACE is not set
 # CONFIG_SIBYTE_SB1250_PROF is not set
 # CONFIG_SIBYTE_TBPROF is not set
-# CONFIG_PCI is not set
 CONFIG_SIBYTE_GENBUS_IDE=y
 CONFIG_SMP_CAPABLE=y
 # CONFIG_SNI_RM200_PCI is not set
@@ -97,7 +100,6 @@ CONFIG_SMP_CAPABLE=y
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-CONFIG_NEW_TIME_C=y
 CONFIG_DUMMY_KEYB=y
 CONFIG_SWAP_IO_SPACE_W=y
 CONFIG_SWAP_IO_SPACE_L=y
@@ -143,9 +145,12 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 # CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_BUILD_ELF64=y
 # CONFIG_BINFMT_IRIX is not set
 CONFIG_NET=y
 # CONFIG_PCI is not set
+# CONFIG_PCI_NEW is not set
+# CONFIG_PCI_AUTO is not set
 # CONFIG_ISA is not set
 # CONFIG_TC is not set
 # CONFIG_MCA is not set
@@ -166,6 +171,7 @@ CONFIG_MIPS32_O32=y
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -195,6 +201,7 @@ CONFIG_BINFMT_ELF32=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_RAM is not set
@@ -237,7 +244,6 @@ CONFIG_INET=y
 #
 #    SCTP Configuration (EXPERIMENTAL)
 #
-CONFIG_IPV6_SCTP__=y
 # CONFIG_IP_SCTP is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
@@ -319,7 +325,6 @@ CONFIG_NETDEVICES=y
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
-CONFIG_NET_SB1250_MAC=y
 # CONFIG_SUNLANCE is not set
 # CONFIG_SUNBMAC is not set
 # CONFIG_SUNQE is not set
@@ -343,6 +348,7 @@ CONFIG_NET_SB1250_MAC=y
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
+CONFIG_NET_SB1250_MAC=y
 # CONFIG_SK98LIN is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_FDDI is not set
@@ -426,6 +432,7 @@ CONFIG_SERIAL_NONSTANDARD=y
 CONFIG_SIBYTE_SB1250_DUART=y
 CONFIG_SIBYTE_SB1250_DUART_CONSOLE=y
 CONFIG_SERIAL_CONSOLE=y
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -468,7 +475,6 @@ CONFIG_UNIX98_PTY_COUNT=256
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/defconfig-sead linux-2.4.29-pre3/arch/mips64/defconfig-sead
--- linux-2.4.28/arch/mips64/defconfig-sead	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/defconfig-sead	2004-12-22 16:06:18.450493040 +0000
@@ -24,10 +24,12 @@ CONFIG_EXPERIMENTAL=y
 # CONFIG_MIPS_DB1000 is not set
 # CONFIG_MIPS_DB1100 is not set
 # CONFIG_MIPS_DB1500 is not set
+# CONFIG_MIPS_DB1550 is not set
 # CONFIG_MIPS_PB1000 is not set
 # CONFIG_MIPS_PB1100 is not set
 # CONFIG_MIPS_PB1500 is not set
 # CONFIG_MIPS_HYDROGEN3 is not set
+# CONFIG_MIPS_PB1550 is not set
 # CONFIG_MIPS_XXS1500 is not set
 # CONFIG_MIPS_MTX1 is not set
 # CONFIG_COGENT_CSB250 is not set
@@ -50,6 +52,8 @@ CONFIG_MIPS_SEAD=y
 # CONFIG_MOMENCO_OCELOT_G is not set
 # CONFIG_MOMENCO_OCELOT_C is not set
 # CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_BIG_SUR is not set
+# CONFIG_PMC_STRETCH is not set
 # CONFIG_PMC_YOSEMITE is not set
 # CONFIG_DDB5074 is not set
 # CONFIG_DDB5476 is not set
@@ -73,9 +77,7 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
 CONFIG_BOOT_ELF32=y
 CONFIG_L1_CACHE_SHIFT=5
-CONFIG_NEW_TIME_C=y
 CONFIG_NONCOHERENT_IO=y
-# CONFIG_PCI is not set
 # CONFIG_MIPS_AU1000 is not set
 
 #
@@ -112,6 +114,7 @@ CONFIG_CPU_HAS_SYNC=y
 # General setup
 #
 CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_BUILD_ELF64 is not set
 # CONFIG_NET is not set
 # CONFIG_PCI is not set
 # CONFIG_ISA is not set
@@ -134,6 +137,7 @@ CONFIG_MIPS32_O32=y
 CONFIG_BINFMT_ELF32=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_OOM_KILLER is not set
+# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -163,6 +167,7 @@ CONFIG_BINFMT_ELF32=y
 # CONFIG_CISS_MONITOR_THREAD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_SX8 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
@@ -237,6 +242,7 @@ CONFIG_SERIAL=y
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
 # CONFIG_UNIX98_PTYS is not set
 
 #
@@ -278,7 +284,6 @@ CONFIG_SERIAL_CONSOLE=y
 # CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_MIPS_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/kernel/Makefile linux-2.4.29-pre3/arch/mips64/kernel/Makefile
--- linux-2.4.28/arch/mips64/kernel/Makefile	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/kernel/Makefile	2004-12-22 16:06:26.016342856 +0000
@@ -17,11 +17,11 @@ export-objs	= irq.o mips64_ksyms.o pci-d
 obj-y		:= branch.o cpu-probe.o entry.o irq.o proc.o process.o \
 		   ptrace.o r4k_cache.o r4k_fpu.o r4k_genex.o r4k_switch.o \
 		   reset.o scall_64.o semaphore.o setup.o signal.o syscall.o \
-		   traps.o unaligned.o
+		   time.o traps.o unaligned.o
 
 obj-$(CONFIG_I8259)		+= i8259.o
 obj-$(CONFIG_IRQ_CPU)		+= irq_cpu.o
-obj-$(CONFIG_NEW_TIME_C)	+= time.o
+obj-$(CONFIG_IRQ_CPU_RM7K)	+= irq-rm7000.o
 
 obj-$(CONFIG_MODULES)		+= mips64_ksyms.o
 obj-$(CONFIG_MIPS32_COMPAT)	+= linux32.o signal32.o ioctl32.o
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/kernel/cpu-probe.c linux-2.4.29-pre3/arch/mips64/kernel/cpu-probe.c
--- linux-2.4.28/arch/mips64/kernel/cpu-probe.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/kernel/cpu-probe.c	2004-12-22 16:07:21.326934368 +0000
@@ -4,7 +4,7 @@
  *	Processor capabilities determination functions.
  *
  *	Copyright (C) xxxx  the Anonymous
- *	Copyright (C) 2003  Maciej W. Rozycki
+ *	Copyright (C) 2003, 2004  Maciej W. Rozycki
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License
@@ -18,6 +18,7 @@
 #include <linux/stddef.h>
 
 #include <asm/bugs.h>
+#include <asm/compiler.h>
 #include <asm/cpu.h>
 #include <asm/fpu.h>
 #include <asm/mipsregs.h>
@@ -92,6 +93,7 @@ static inline void check_wait(void)
 	case CPU_R5000:
 	case CPU_NEVADA:
 	case CPU_RM7000:
+	case CPU_RM9000:
 	case CPU_TX49XX:
 	case CPU_4KC:
 	case CPU_4KEC:
@@ -179,7 +181,7 @@ static inline void mult_sh_align_mod(lon
 		".set	pop"
 		: "=&r" (lv1), "=r" (lw)
 		: "r" (m1), "r" (m2), "r" (s), "I" (0)
-		: "hi", "lo", "accum");
+		: "hi", "lo", GCC_REG_ACCUM);
 	/* We have to use single integers for m1 and m2 and a double
 	 * one for p to be sure the mulsidi3 gcc's RTL multiplication
 	 * instruction has the workaround applied.  Older versions of
@@ -274,7 +276,7 @@ static inline void check_daddi(void)
 	extern asmlinkage void handle_daddi_ov(void);
 	unsigned long flags;
 	void *handler;
-	long v;
+	long v, tmp;
 
 	printk("Checking for the daddi bug... ");
 
@@ -294,13 +296,15 @@ static inline void check_daddi(void)
 		".set	noat\n\t"
 		".set	noreorder\n\t"
 		".set	nomacro\n\t"
+		"addiu	%1, $0, %2\n\t"
+		"dsrl	%1, %1, 1\n\t"
 #ifdef HAVE_AS_SET_DADDI
 		".set	daddi\n\t"
 #endif
-		"daddi	%0, %1, %2\n\t"
+		"daddi	%0, %1, %3\n\t"
 		".set	pop"
-		: "=r" (v)
-		: "r" (0x7fffffffffffedcd), "I" (0x1234));
+		: "=r" (v), "=&r" (tmp)
+		: "I" (0xffffffffffffdb9a), "I" (0x1234));
 	set_except_vector(12, handler);
 	local_irq_restore(flags);
 
@@ -314,9 +318,11 @@ static inline void check_daddi(void)
 	local_irq_save(flags);
 	handler = set_except_vector(12, handle_daddi_ov);
 	asm volatile(
-		"daddi	%0, %1, %2"
-		: "=r" (v)
-		: "r" (0x7fffffffffffedcd), "I" (0x1234));
+		"addiu	%1, $0, %2\n\t"
+		"dsrl	%1, %1, 1\n\t"
+		"daddi	%0, %1, %3"
+		: "=r" (v), "=&r" (tmp)
+		: "I" (0xffffffffffffdb9a), "I" (0x1234));
 	set_except_vector(12, handler);
 	local_irq_restore(flags);
 
@@ -337,7 +343,7 @@ static inline void check_daddi(void)
 
 static inline void check_daddiu(void)
 {
-	long v, w;
+	long v, w, tmp;
 
 	printk("Checking for the daddiu bug... ");
 
@@ -362,15 +368,17 @@ static inline void check_daddiu(void)
 		".set	noat\n\t"
 		".set	noreorder\n\t"
 		".set	nomacro\n\t"
+		"addiu	%2, $0, %3\n\t"
+		"dsrl	%2, %2, 1\n\t"
 #ifdef HAVE_AS_SET_DADDI
 		".set	daddi\n\t"
 #endif
-		"daddiu	%0, %2, %3\n\t"
-		"addiu	%1, $0, %3\n\t"
+		"daddiu	%0, %2, %4\n\t"
+		"addiu	%1, $0, %4\n\t"
 		"daddu	%1, %2\n\t"
 		".set	pop"
-		: "=&r" (v), "=&r" (w)
-		: "r" (0x7fffffffffffedcd), "I" (0x1234));
+		: "=&r" (v), "=&r" (w), "=&r" (tmp)
+		: "I" (0xffffffffffffdb9a), "I" (0x1234));
 
 	if (v == w) {
 		printk("no.\n");
@@ -380,11 +388,13 @@ static inline void check_daddiu(void)
 	printk("yes, workaround... ");
 
 	asm volatile(
-		"daddiu	%0, %2, %3\n\t"
-		"addiu	%1, $0, %3\n\t"
+		"addiu	%2, $0, %3\n\t"
+		"dsrl	%2, %2, 1\n\t"
+		"daddiu	%0, %2, %4\n\t"
+		"addiu	%1, $0, %4\n\t"
 		"daddu	%1, %2"
-		: "=&r" (v), "=&r" (w)
-		: "r" (0x7fffffffffffedcd), "I" (0x1234));
+		: "=&r" (v), "=&r" (w), "=&r" (tmp)
+		: "I" (0xffffffffffffdb9a), "I" (0x1234));
 
 	if (v == w) {
 		printk("yes.\n");
@@ -462,8 +472,7 @@ static inline void cpu_probe_legacy(stru
 	case PRID_IMP_R2000:
 		c->cputype = CPU_R2000;
 		c->isa_level = MIPS_CPU_ISA_I;
-		c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX |
-		             MIPS_CPU_LLSC;
+		c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX;
 		if (__cpu_has_fpu())
 			c->options |= MIPS_CPU_FPU;
 		c->tlbsize = 64;
@@ -477,17 +486,24 @@ static inline void cpu_probe_legacy(stru
 		else
 			c->cputype = CPU_R3000;
 		c->isa_level = MIPS_CPU_ISA_I;
-		c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX |
-		             MIPS_CPU_LLSC;
+		c->options = MIPS_CPU_TLB | MIPS_CPU_NOFPUEX; 
 		if (__cpu_has_fpu())
 			c->options |= MIPS_CPU_FPU;
 		c->tlbsize = 64;
 		break;
 	case PRID_IMP_R4000:
-		if ((c->processor_id & 0xff) >= PRID_REV_R4400)
-			c->cputype = CPU_R4400SC;
-		else
-			c->cputype = CPU_R4000SC;
+		if (read_c0_config() & CONF_SC) {
+			if ((c->processor_id & 0xff) >= PRID_REV_R4400)
+				c->cputype = CPU_R4400PC;
+			else
+				c->cputype = CPU_R4000PC;
+		} else {
+			if ((c->processor_id & 0xff) >= PRID_REV_R4400)
+				c->cputype = CPU_R4400SC;
+			else
+				c->cputype = CPU_R4000SC;
+		}
+
 		c->isa_level = MIPS_CPU_ISA_III;
 		c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
 		             MIPS_CPU_WATCH | MIPS_CPU_VCE |
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/kernel/gdb-low.S linux-2.4.29-pre3/arch/mips64/kernel/gdb-low.S
--- linux-2.4.28/arch/mips64/kernel/gdb-low.S	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/kernel/gdb-low.S	2004-12-22 16:06:54.613995352 +0000
@@ -283,7 +283,7 @@
 		ld	v0,GDB_FR_HI(sp)
 		ld	v1,GDB_FR_LO(sp)
 		mthi	v0
-		mtlo	v0
+		mtlo	v1
 		ld	ra,GDB_FR_REG31(sp)
 		ld	fp,GDB_FR_REG30(sp)
 		ld	gp,GDB_FR_REG28(sp)
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/kernel/ioctl32.c linux-2.4.29-pre3/arch/mips64/kernel/ioctl32.c
--- linux-2.4.28/arch/mips64/kernel/ioctl32.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/kernel/ioctl32.c	2004-12-22 16:06:43.934618864 +0000
@@ -44,6 +44,7 @@
 #include <linux/blkpg.h>
 #include <linux/blk.h>
 #include <linux/elevator.h>
+#include <linux/file.h>
 #include <linux/rtc.h>
 #include <linux/pci.h>
 #if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
@@ -1817,7 +1818,6 @@ static struct ioctl32_list ioctl32_handl
 	IOCTL32_DEFAULT(_IOR('v' , BASE_VIDIOCPRIVATE+6, int)),
 	IOCTL32_DEFAULT(_IOR('v' , BASE_VIDIOCPRIVATE+7, int)),
 
-#ifdef CONFIG_NET
 	/* Socket level stuff */
 	IOCTL32_DEFAULT(FIOSETOWN),
 	IOCTL32_DEFAULT(SIOCSPGRP),
@@ -2079,6 +2079,7 @@ static struct ioctl32_list ioctl32_handl
 	IOCTL32_DEFAULT(SOUND_MIXER_SETLEVELS),
 	IOCTL32_DEFAULT(OSS_GETVERSION),
 
+#ifdef CONFIG_NET
 	/* And these ioctls need translation */
 	IOCTL32_HANDLER(SIOCGIFNAME, dev_ifname32),
 	IOCTL32_HANDLER(SIOCGIFCONF, dev_ifconf),
@@ -2120,7 +2121,6 @@ static struct ioctl32_list ioctl32_handl
 	 */
 	IOCTL32_HANDLER(SIOCRTMSG, ret_einval),
 	IOCTL32_HANDLER(SIOCGSTAMP, do_siocgstamp),
-
 #endif /* CONFIG_NET */
 
 	IOCTL32_HANDLER(BLKRAGET, w_long),
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/kernel/irq-rm7000.c linux-2.4.29-pre3/arch/mips64/kernel/irq-rm7000.c
--- linux-2.4.28/arch/mips64/kernel/irq-rm7000.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/kernel/irq-rm7000.c	2004-12-22 16:06:34.889993856 +0000
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2003 Ralf Baechle
+ *
+ * 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.
+ *
+ * Handler for RM7000 extended interrupts.  These are a non-standard
+ * feature so we handle them separately from standard interrupts.
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+static int irq_base;
+
+static inline void unmask_rm7k_irq(unsigned int irq)
+{
+	set_c0_intcontrol(0x100 << (irq - irq_base));
+}
+
+static inline void mask_rm7k_irq(unsigned int irq)
+{
+	clear_c0_intcontrol(0x100 << (irq - irq_base));
+}
+
+static inline void rm7k_cpu_irq_enable(unsigned int irq)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	unmask_rm7k_irq(irq);
+	local_irq_restore(flags);
+}
+
+static void rm7k_cpu_irq_disable(unsigned int irq)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	mask_rm7k_irq(irq);
+	local_irq_restore(flags);
+}
+
+static unsigned int rm7k_cpu_irq_startup(unsigned int irq)
+{
+	rm7k_cpu_irq_enable(irq);
+
+	return 0;
+}
+
+#define	rm7k_cpu_irq_shutdown	rm7k_cpu_irq_disable
+
+/*
+ * While we ack the interrupt interrupts are disabled and thus we don't need
+ * to deal with concurrency issues.  Same for rm7k_cpu_irq_end.
+ */
+static void rm7k_cpu_irq_ack(unsigned int irq)
+{
+	mask_rm7k_irq(irq);
+}
+
+static void rm7k_cpu_irq_end(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		unmask_rm7k_irq(irq);
+}
+
+static hw_irq_controller rm7k_irq_controller = {
+	"RM7000",
+	rm7k_cpu_irq_startup,
+	rm7k_cpu_irq_shutdown,
+	rm7k_cpu_irq_enable,
+	rm7k_cpu_irq_disable,
+	rm7k_cpu_irq_ack,
+	rm7k_cpu_irq_end,
+};
+
+void __init rm7k_cpu_irq_init(int base)
+{
+	int i;
+
+	clear_c0_intcontrol(0x00000f00);		/* Mask all */
+
+	for (i = base; i < base + 4; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		irq_desc[i].action = NULL;
+		irq_desc[i].depth = 1;
+		irq_desc[i].handler = &rm7k_irq_controller;
+	}
+
+	irq_base = base;
+}
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/kernel/irq_cpu.c linux-2.4.29-pre3/arch/mips64/kernel/irq_cpu.c
--- linux-2.4.28/arch/mips64/kernel/irq_cpu.c	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/kernel/irq_cpu.c	2004-12-22 16:06:58.451411976 +0000
@@ -16,18 +16,20 @@
  * Almost all MIPS CPUs define 8 interrupt sources.  They are typically
  * level triggered (i.e., cannot be cleared from CPU; must be cleared from
  * device).  The first two are software interrupts which we don't really
- * use or support.  The last one is usually cpu timer interrupt if a counter
- * register is present.
+ * use or support.  The last one is usually the CPU timer interrupt if
+ * counter register is present or, for CPUs with an external FPU, by
+ * convention it's the FPU exception interrupt.
  *
  * Don't even think about using this on SMP.  You have been warned.
  *
  * This file exports one global function:
- *	mips_cpu_irq_init(u32 irq_base);
+ *	void mips_cpu_irq_init(int irq_base);
  */
+#include <linux/init.h>
 #include <linux/interrupt.h>
-#include <linux/types.h>
 #include <linux/kernel.h>
 
+#include <asm/irq_cpu.h>
 #include <asm/mipsregs.h>
 #include <asm/system.h>
 
@@ -78,7 +80,7 @@ static unsigned int mips_cpu_irq_startup
 static void mips_cpu_irq_ack(unsigned int irq)
 {
 	/* Only necessary for soft interrupts */
-	clear_c0_cause(1 << (irq - mips_cpu_irq_base + 8));
+	clear_c0_cause(0x100 << (irq - mips_cpu_irq_base));
 
 	mask_mips_irq(irq);
 }
@@ -90,7 +92,7 @@ static void mips_cpu_irq_end(unsigned in
 }
 
 static hw_irq_controller mips_cpu_irq_controller = {
-	"CPU_irq",
+	"MIPS",
 	mips_cpu_irq_startup,
 	mips_cpu_irq_shutdown,
 	mips_cpu_irq_enable,
@@ -101,9 +103,9 @@ static hw_irq_controller mips_cpu_irq_co
 };
 
 
-void mips_cpu_irq_init(u32 irq_base)
+void __init mips_cpu_irq_init(int irq_base)
 {
-	u32 i;
+	int i;
 
 	for (i = irq_base; i < irq_base + 8; i++) {
 		irq_desc[i].status = IRQ_DISABLED;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/kernel/linux32.c linux-2.4.29-pre3/arch/mips64/kernel/linux32.c
--- linux-2.4.28/arch/mips64/kernel/linux32.c	2004-12-22 16:17:15.658582224 +0000
+++ linux-2.4.29-pre3/arch/mips64/kernel/linux32.c	2004-12-22 16:07:03.376663224 +0000
@@ -487,6 +487,8 @@ static int nargs(unsigned int arg, char 
 			*ap++ = (char *) A(addr);
 		arg += sizeof(unsigned int);
 		n++;
+		if (n >= (MAX_ARG_PAGES * PAGE_SIZE) / sizeof(char *))
+			return -E2BIG;
 	} while (addr);
 	return n - 1;
 }
@@ -2166,9 +2168,10 @@ do_sys32_shmctl (int first, int second, 
 
 static inline void *alloc_user_space(long len)
 {
-	unsigned long sp = (unsigned long) current + THREAD_SIZE - 32;
+	struct pt_regs *regs = (struct pt_regs *)
+		((unsigned long) current + THREAD_SIZE - 32) - 1;
  
-	return (void *) (sp - len);
+	return (void *) (regs->regs[29] - len);
 }
 
 static int sys32_semtimedop(int semid, struct sembuf *tsems, int nsems,
@@ -2480,6 +2483,12 @@ struct cmsghdr32 {
 				    (struct cmsghdr32 *)(ctl) : \
 				    (struct cmsghdr32 *)NULL)
 #define CMSG32_FIRSTHDR(msg)	__CMSG32_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
+#define CMSG32_OK(ucmlen, ucmsg, mhdr) \
+	((ucmlen) >= sizeof(struct cmsghdr) && \
+	 (ucmlen) <= (unsigned long) \
+	 ((mhdr)->msg_controllen - \
+	  ((char *)(ucmsg) - (char *)(mhdr)->msg_control)))
+
 
 __inline__ struct cmsghdr32 *__cmsg32_nxthdr(void *__ctl, __kernel_size_t __size,
 					      struct cmsghdr32 *__cmsg, int __cmsg_len)
@@ -2620,11 +2629,7 @@ static int cmsghdr_from_user32_to_kern(s
 			return -EFAULT;
 
 		/* Catch bogons. */
-		if(CMSG32_ALIGN(ucmlen) <
-		   CMSG32_ALIGN(sizeof(struct cmsghdr32)))
-			return -ENOBUFS;
-		if((unsigned long)(((char *)ucmsg - (char *)kmsg->msg_control)
-				   + ucmlen) > kmsg->msg_controllen)
+		if (!CMSG32_OK(ucmlen, ucmsg, kmsg))
 			return -EINVAL;
 
 		tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
@@ -3097,36 +3102,378 @@ asmlinkage long sys32_socketcall(int cal
 
 #ifdef CONFIG_MODULES
 
-/* From sparc64 */
+extern asmlinkage unsigned long sys_create_module(const char *name_user, size_t size);
 
-struct kernel_sym32 {
-        u32 value;
-        char name[60];
+asmlinkage unsigned long sys32_create_module(const char *name_user, __kernel_size_t32 size)
+{
+	return sys_create_module(name_user, (size_t)size);
+}
+
+extern asmlinkage int sys_init_module(const char *name_user, struct module *mod_user);
+
+/* Hey, when you're trying to init module, take time and prepare us a nice 64bit
+ * module structure, even if from 32bit modutils... Why to pollute kernel... :))
+ */
+asmlinkage int sys32_init_module(const char *name_user, struct module *mod_user)
+{
+	return sys_init_module(name_user, mod_user);
+}
+
+extern asmlinkage int sys_delete_module(const char *name_user);
+
+asmlinkage int sys32_delete_module(const char *name_user)
+{
+	return sys_delete_module(name_user);
+}
+
+struct module_info32 {
+	u32 addr;
+	u32 size;
+	u32 flags;
+	s32 usecount;
 };
 
+/* Query various bits about modules.  */
+
+static inline long
+get_mod_name(const char *user_name, char **buf)
+{
+	unsigned long page;
+	long retval;
+
+	if ((unsigned long)user_name >= TASK_SIZE
+	    && !segment_eq(get_fs (), KERNEL_DS))
+		return -EFAULT;
+
+	page = __get_free_page(GFP_KERNEL);
+	if (!page)
+		return -ENOMEM;
+
+	retval = strncpy_from_user((char *)page, user_name, PAGE_SIZE);
+	if (retval > 0) {
+		if (retval < PAGE_SIZE) {
+			*buf = (char *)page;
+			return retval;
+		}
+		retval = -ENAMETOOLONG;
+	} else if (!retval)
+		retval = -EINVAL;
+
+	free_page(page);
+	return retval;
+}
+
+static inline void
+put_mod_name(char *buf)
+{
+	free_page((unsigned long)buf);
+}
+
+static __inline__ struct module *find_module(const char *name)
+{
+	struct module *mod;
+
+	for (mod = module_list; mod ; mod = mod->next) {
+		if (mod->flags & MOD_DELETED)
+			continue;
+		if (!strcmp(mod->name, name))
+			break;
+	}
+
+	return mod;
+}
+
+static int
+qm_modules(char *buf, size_t bufsize, __kernel_size_t32 *ret)
+{
+	struct module *mod;
+	size_t nmod, space, len;
+
+	nmod = space = 0;
+
+	for (mod = module_list; mod->next != NULL; mod = mod->next, ++nmod) {
+		len = strlen(mod->name)+1;
+		if (len > bufsize)
+			goto calc_space_needed;
+		if (copy_to_user(buf, mod->name, len))
+			return -EFAULT;
+		buf += len;
+		bufsize -= len;
+		space += len;
+	}
+
+	if (put_user(nmod, ret))
+		return -EFAULT;
+	else
+		return 0;
+
+calc_space_needed:
+	space += len;
+	while ((mod = mod->next)->next != NULL)
+		space += strlen(mod->name)+1;
+
+	if (put_user(space, ret))
+		return -EFAULT;
+	else
+		return -ENOSPC;
+}
+
+static int
+qm_deps(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
+{
+	size_t i, space, len;
+
+	if (mod->next == NULL)
+		return -EINVAL;
+	if (!MOD_CAN_QUERY(mod))
+		return put_user(0, ret);
+
+	space = 0;
+	for (i = 0; i < mod->ndeps; ++i) {
+		const char *dep_name = mod->deps[i].dep->name;
+
+		len = strlen(dep_name)+1;
+		if (len > bufsize)
+			goto calc_space_needed;
+		if (copy_to_user(buf, dep_name, len))
+			return -EFAULT;
+		buf += len;
+		bufsize -= len;
+		space += len;
+	}
+
+	return put_user(i, ret);
+
+calc_space_needed:
+	space += len;
+	while (++i < mod->ndeps)
+		space += strlen(mod->deps[i].dep->name)+1;
+
+	if (put_user(space, ret))
+		return -EFAULT;
+	else
+		return -ENOSPC;
+}
+
+static int
+qm_refs(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
+{
+	size_t nrefs, space, len;
+	struct module_ref *ref;
+
+	if (mod->next == NULL)
+		return -EINVAL;
+	if (!MOD_CAN_QUERY(mod))
+		if (put_user(0, ret))
+			return -EFAULT;
+		else
+			return 0;
+
+	space = 0;
+	for (nrefs = 0, ref = mod->refs; ref ; ++nrefs, ref = ref->next_ref) {
+		const char *ref_name = ref->ref->name;
+
+		len = strlen(ref_name)+1;
+		if (len > bufsize)
+			goto calc_space_needed;
+		if (copy_to_user(buf, ref_name, len))
+			return -EFAULT;
+		buf += len;
+		bufsize -= len;
+		space += len;
+	}
+
+	if (put_user(nrefs, ret))
+		return -EFAULT;
+	else
+		return 0;
+
+calc_space_needed:
+	space += len;
+	while ((ref = ref->next_ref) != NULL)
+		space += strlen(ref->ref->name)+1;
+
+	if (put_user(space, ret))
+		return -EFAULT;
+	else
+		return -ENOSPC;
+}
+
+static inline int
+qm_symbols(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
+{
+	size_t i, space, len;
+	struct module_symbol *s;
+	char *strings;
+	unsigned *vals;
+
+	if (!MOD_CAN_QUERY(mod))
+		if (put_user(0, ret))
+			return -EFAULT;
+		else
+			return 0;
+
+	space = mod->nsyms * 2*sizeof(u32);
+
+	i = len = 0;
+	s = mod->syms;
+
+	if (space > bufsize)
+		goto calc_space_needed;
+
+	if (!access_ok(VERIFY_WRITE, buf, space))
+		return -EFAULT;
+
+	bufsize -= space;
+	vals = (unsigned *)buf;
+	strings = buf+space;
+
+	for (; i < mod->nsyms ; ++i, ++s, vals += 2) {
+		len = strlen(s->name)+1;
+		if (len > bufsize)
+			goto calc_space_needed;
+
+		if (copy_to_user(strings, s->name, len)
+		    || __put_user(s->value, vals+0)
+		    || __put_user(space, vals+1))
+			return -EFAULT;
+
+		strings += len;
+		bufsize -= len;
+		space += len;
+	}
+
+	if (put_user(i, ret))
+		return -EFAULT;
+	else
+		return 0;
+
+calc_space_needed:
+	for (; i < mod->nsyms; ++i, ++s)
+		space += strlen(s->name)+1;
+
+	if (put_user(space, ret))
+		return -EFAULT;
+	else
+		return -ENOSPC;
+}
+
+static inline int
+qm_info(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
+{
+	int error = 0;
+
+	if (mod->next == NULL)
+		return -EINVAL;
+
+	if (sizeof(struct module_info32) <= bufsize) {
+		struct module_info32 info;
+		info.addr = (unsigned long)mod;
+		info.size = mod->size;
+		info.flags = mod->flags;
+		info.usecount =
+			((mod_member_present(mod, can_unload)
+			  && mod->can_unload)
+			 ? -1 : atomic_read(&mod->uc.usecount));
+
+		if (copy_to_user(buf, &info, sizeof(struct module_info32)))
+			return -EFAULT;
+	} else
+		error = -ENOSPC;
+
+	if (put_user(sizeof(struct module_info32), ret))
+		return -EFAULT;
+
+	return error;
+}
+
+asmlinkage int sys32_query_module(char *name_user, int which, char *buf, __kernel_size_t32 bufsize, u32 ret)
+{
+	struct module *mod;
+	int err;
+
+	lock_kernel();
+	if (name_user == 0) {
+		/* This finds "kernel_module" which is not exported. */
+		for(mod = module_list; mod->next != NULL; mod = mod->next)
+			;
+	} else {
+		long namelen;
+		char *name;
+
+		if ((namelen = get_mod_name(name_user, &name)) < 0) {
+			err = namelen;
+			goto out;
+		}
+		err = -ENOENT;
+		if (namelen == 0) {
+			/* This finds "kernel_module" which is not exported. */
+			for(mod = module_list; mod->next != NULL; mod = mod->next)
+				;
+		} else if ((mod = find_module(name)) == NULL) {
+			put_mod_name(name);
+			goto out;
+		}
+		put_mod_name(name);
+	}
+
+	switch (which)
+	{
+	case 0:
+		err = 0;
+		break;
+	case QM_MODULES:
+		err = qm_modules(buf, bufsize, (__kernel_size_t32 *)AA(ret));
+		break;
+	case QM_DEPS:
+		err = qm_deps(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
+		break;
+	case QM_REFS:
+		err = qm_refs(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
+		break;
+	case QM_SYMBOLS:
+		err = qm_symbols(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
+		break;
+	case QM_INFO:
+		err = qm_info(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
+		break;
+	default:
+		err = -EINVAL;
+		break;
+	}
+out:
+	unlock_kernel();
+	return err;
+}
+
+struct kernel_sym32 {
+	u32 value;
+	char name[60];
+};
+		 
 extern asmlinkage int sys_get_kernel_syms(struct kernel_sym *table);
 
 asmlinkage int sys32_get_kernel_syms(struct kernel_sym32 *table)
 {
-        int len, i;
-        struct kernel_sym *tbl;
-        mm_segment_t old_fs;
-
-        len = sys_get_kernel_syms(NULL);
-        if (!table) return len;
-        tbl = kmalloc (len * sizeof (struct kernel_sym), GFP_KERNEL);
-        if (!tbl) return -ENOMEM;
-        old_fs = get_fs();
-        set_fs (KERNEL_DS);
-        sys_get_kernel_syms(tbl);
-        set_fs (old_fs);
-        for (i = 0; i < len; i++, table++) {
-                if (put_user (tbl[i].value, &table->value) ||
-                    copy_to_user (table->name, tbl[i].name, 60))
-                        break;
-        }
-        kfree (tbl);
-        return i;
+	int len, i;
+	struct kernel_sym *tbl;
+	mm_segment_t old_fs;
+	
+	len = sys_get_kernel_syms(NULL);
+	if (!table) return len;
+	tbl = kmalloc (len * sizeof (struct kernel_sym), GFP_KERNEL);
+	if (!tbl) return -ENOMEM;
+	old_fs = get_fs();
+	set_fs (KERNEL_DS);
+	sys_get_kernel_syms(tbl);
+	set_fs (old_fs);
+	for (i = 0; i < len; i++, table++) {
+		if (put_user (tbl[i].value, &table->value) ||
+		    copy_to_user (table->name, tbl[i].name, 60))
+			break;
+	}
+	kfree (tbl);
+	return i;
 }
 
 #else /* CONFIG_MODULES */
@@ -3161,10 +3508,10 @@ sys32_query_module(const char *name_user
 	return -ENOSYS;
 }
 
-asmlinkage long
+asmlinkage int
 sys32_get_kernel_syms(struct kernel_sym *table)
 {
 	return -ENOSYS;
 }
 
-#endif /* CONFIG_MODULES */
+#endif  /* CONFIG_MODULES */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/kernel/mips64_ksyms.c linux-2.4.29-pre3/arch/mips64/kernel/mips64_ksyms.c
--- linux-2.4.28/arch/mips64/kernel/mips64_ksyms.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/kernel/mips64_ksyms.c	2004-12-22 16:06:27.042186904 +0000
@@ -53,10 +53,15 @@ EXPORT_SYMBOL_NOVERS(memcmp);
 EXPORT_SYMBOL_NOVERS(memset);
 EXPORT_SYMBOL_NOVERS(memcpy);
 EXPORT_SYMBOL_NOVERS(memmove);
+EXPORT_SYMBOL_NOVERS(memscan);
+EXPORT_SYMBOL_NOVERS(strcpy);
+EXPORT_SYMBOL_NOVERS(strncpy);
 EXPORT_SYMBOL_NOVERS(strcat);
 EXPORT_SYMBOL_NOVERS(strchr);
+EXPORT_SYMBOL_NOVERS(strncmp);
 EXPORT_SYMBOL_NOVERS(strlen);
 EXPORT_SYMBOL_NOVERS(strncat);
+EXPORT_SYMBOL_NOVERS(strcmp);
 EXPORT_SYMBOL_NOVERS(strnlen);
 EXPORT_SYMBOL_NOVERS(strrchr);
 EXPORT_SYMBOL_NOVERS(strtok);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/kernel/proc.c linux-2.4.29-pre3/arch/mips64/kernel/proc.c
--- linux-2.4.28/arch/mips64/kernel/proc.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/kernel/proc.c	2004-12-22 16:07:42.330741304 +0000
@@ -48,7 +48,6 @@ static const char *cpu_name[] = {
 	[CPU_R4640]	"R4640",
 	[CPU_NEVADA]	"Nevada",
 	[CPU_RM7000]	"RM7000",
-	[CPU_RM9000]	"RM9000",
 	[CPU_R5432]	"R5432",
 	[CPU_4KC]	"MIPS 4Kc",
         [CPU_5KC]	"MIPS 5Kc",
@@ -58,23 +57,27 @@ static const char *cpu_name[] = {
 	[CPU_TX3922]	"TX3922",
 	[CPU_TX3927]	"TX3927",
 	[CPU_AU1000]	"Au1000",
-	[CPU_AU1500]	"Au1500",
 	[CPU_4KEC]	"MIPS 4KEc",
 	[CPU_4KSC]	"MIPS 4KSc",
 	[CPU_VR41XX]	"NEC Vr41xx",
 	[CPU_R5500]	"R5500",
 	[CPU_TX49XX]	"TX49xx",
+	[CPU_AU1500]	"Au1500",
 	[CPU_20KC]	"MIPS 20Kc",
-	[CPU_24K]	"MIPS 24K",
-	[CPU_25KF]	"MIPS 25Kf",
 	[CPU_VR4111]	"NEC VR4111",
 	[CPU_VR4121]	"NEC VR4121",
 	[CPU_VR4122]	"NEC VR4122",
 	[CPU_VR4131]	"NEC VR4131",
-	[CPU_VR4133]	"NEC VR4133",
 	[CPU_VR4181]	"NEC VR4181",
 	[CPU_VR4181A]	"NEC VR4181A",
-	[CPU_SR71000]	"Sandcraft SR71000"
+	[CPU_AU1100]	"Au1100",
+	[CPU_SR71000]	"Sandcraft SR71000",
+	[CPU_RM9000]	"RM9000",
+	[CPU_25KF]	"MIPS 25Kf",
+	[CPU_VR4133]	"NEC VR4133",
+	[CPU_AU1550]	"Au1550",
+	[CPU_24K]	"MIPS 24K",
+	[CPU_AU1200]	"Au1200",
 };
 
 
@@ -116,7 +119,7 @@ static int show_cpuinfo(struct seq_file 
 	              cpu_has_watch ? "yes" : "no");
 
 	sprintf(fmt, "VCE%%c exceptions\t\t: %s\n",
-	        cpu_has_vce ? "%d" : "not available");
+	        cpu_has_vce ? "%u" : "not available");
 	seq_printf(m, fmt, 'D', vced_count);
 	seq_printf(m, fmt, 'I', vcei_count);
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/kernel/scall_64.S linux-2.4.29-pre3/arch/mips64/kernel/scall_64.S
--- linux-2.4.28/arch/mips64/kernel/scall_64.S	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/kernel/scall_64.S	2004-12-22 16:05:45.406516488 +0000
@@ -31,13 +31,15 @@ NESTED(handle_sys64, PT_SIZE, sp)
 	STI
 	.set	at
 #endif
-	ld	t1, PT_EPC(sp)		# skip syscall on return
 
 	subu	t0, v0, __NR_64_Linux	# check syscall number
 	sltiu	t0, t0,	__NR_64_Linux_syscalls + 1
+#if !defined(CONFIG_MIPS32_O32) && !defined(CONFIG_MIPS32_N32)
+	ld	t1, PT_EPC(sp)		# skip syscall on return
 	daddiu	t1, 4			# skip to next instruction
-	beqz	t0, illegal_syscall
 	sd	t1, PT_EPC(sp)
+#endif
+	beqz	t0, illegal_syscall
 
 	dsll	t0, v0, 3		# offset into table
 	ld	t2, (sys_call_table - (__NR_64_Linux * 8))(t0) # syscall routine
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/kernel/scall_n32.S linux-2.4.29-pre3/arch/mips64/kernel/scall_n32.S
--- linux-2.4.28/arch/mips64/kernel/scall_n32.S	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/kernel/scall_n32.S	2004-12-22 16:06:34.145107096 +0000
@@ -35,13 +35,16 @@ NESTED(handle_sysn32, PT_SIZE, sp)
 	STI
 	.set	at
 #endif
-	ld	t1, PT_EPC(sp)		# skip syscall on return
 
 	subu	t0, v0, __NR_N32_Linux	# check syscall number
 	sltiu	t0, t0,	__NR_N32_Linux_syscalls + 1
+
+#ifndef CONFIG_MIPS32_O32
+	ld	t1, PT_EPC(sp)		# skip syscall on return
 	daddiu	t1, 4			# skip to next instruction
-	beqz	t0, not_n32_scall
 	sd	t1, PT_EPC(sp)
+#endif
+	beqz	t0, not_n32_scall
 
 	dsll	t0, v0, 3		# offset into table
 	ld	t2, (sysn32_call_table - (__NR_N32_Linux * 8))(t0)
@@ -300,11 +303,11 @@ EXPORT(sysn32_call_table)
 	PTR	sys_reboot
 	PTR	sys_sethostname			/* 6165 */
 	PTR	sys_setdomainname
-	PTR	sys_create_module
-	PTR	sys_init_module
-	PTR	sys_delete_module
-	PTR	sys_get_kernel_syms		/* 6170 */
-	PTR	sys_query_module
+	PTR	sys32_create_module
+	PTR	sys32_init_module
+	PTR	sys32_delete_module
+	PTR	sys32_get_kernel_syms		/* 6170 */
+	PTR	sys32_query_module
 	PTR	sys_quotactl
 	PTR	sys_nfsservctl
 	PTR	sys_ni_syscall			/* res. for getpmsg */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/kernel/scall_o32.S linux-2.4.29-pre3/arch/mips64/kernel/scall_o32.S
--- linux-2.4.28/arch/mips64/kernel/scall_o32.S	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/kernel/scall_o32.S	2004-12-22 16:07:16.988593896 +0000
@@ -33,8 +33,8 @@ NESTED(handle_sys, PT_SIZE, sp)
 	subu	t0, v0, __NR_O32_Linux	# check syscall number
 	sltiu	t0, t0, __NR_O32_Linux_syscalls + 1
 	daddiu	t1, 4			# skip to next instruction
-	beqz	t0, not_o32_scall
 	sd	t1, PT_EPC(sp)
+	beqz	t0, not_o32_scall
 #if 0
  SAVE_ALL
  move a1, v0
@@ -451,9 +451,9 @@ out:	jr	ra
 	sys	sys32_adjtimex	1
 	sys	sys_mprotect	3			/* 4125 */
 	sys	sys32_sigprocmask	3
-	sys	sys_create_module 2
-	sys	sys_init_module	5
-	sys	sys_delete_module 1
+	sys	sys32_create_module 2
+	sys	sys32_init_module	5
+	sys	sys32_delete_module 1
 	sys	sys32_get_kernel_syms 1			/* 4130 */
 	sys	sys_quotactl	0
 	sys	sys_getpgid	1
@@ -511,7 +511,7 @@ out:	jr	ra
 	sys	sys_socketpair	4
 	sys	sys_setresuid	3			/* 4185 */
 	sys	sys_getresuid	3
-	sys	sys_query_module 5
+	sys	sys32_query_module 5
 	sys	sys_poll	3
 	sys	sys_nfsservctl	3
 	sys	sys_setresgid	3			/* 4190 */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/kernel/semaphore.c linux-2.4.29-pre3/arch/mips64/kernel/semaphore.c
--- linux-2.4.28/arch/mips64/kernel/semaphore.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/kernel/semaphore.c	2004-12-22 16:06:24.908511272 +0000
@@ -8,7 +8,7 @@
 #include <linux/module.h>
 #include <linux/sched.h>
 
-#ifdef CONFIG_CPU_HAS_LLDSCD
+#ifndef CONFIG_CPU_HAS_LLDSCD
 /*
  * On machines without lld/scd we need a spinlock to make the manipulation of
  * sem->count and sem->waking atomic.  Scalability isn't an issue because
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/kernel/setup.c linux-2.4.29-pre3/arch/mips64/kernel/setup.c
--- linux-2.4.28/arch/mips64/kernel/setup.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/kernel/setup.c	2004-12-22 16:05:31.529626096 +0000
@@ -41,6 +41,7 @@
 #include <asm/pgalloc.h>
 
 struct cpuinfo_mips cpu_data[NR_CPUS];
+EXPORT_SYMBOL(cpu_data);
 
 #ifdef CONFIG_VT
 struct screen_info screen_info;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/kernel/signal.c linux-2.4.29-pre3/arch/mips64/kernel/signal.c
--- linux-2.4.28/arch/mips64/kernel/signal.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/kernel/signal.c	2004-12-22 16:06:02.780875184 +0000
@@ -265,7 +265,7 @@ static inline void *get_sigframe(struct 
  	sp -= 32;
 
 	/* This is the X/Open sanctioned signal stack switching.  */
-	if ((ka->sa.sa_flags & SA_ONSTACK) && ! on_sig_stack(sp))
+	if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
 		sp = current->sas_ss_sp + current->sas_ss_size;
 
 	return (void *)((sp - frame_size) & ALMASK);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/kernel/signal32.c linux-2.4.29-pre3/arch/mips64/kernel/signal32.c
--- linux-2.4.28/arch/mips64/kernel/signal32.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/kernel/signal32.c	2004-12-22 16:06:46.898168336 +0000
@@ -67,6 +67,71 @@ typedef struct sigaltstack32 {
 	int ss_flags;
 } stack32_t;
 
+typedef union sigval32 {
+	int sival_int;
+	s32 sival_ptr;
+} sigval_t32;
+
+#define SI_PAD_SIZE32	((SI_MAX_SIZE/sizeof(int)) - 3)
+
+typedef struct siginfo32 {
+	int si_signo;
+	int si_code;
+	int si_errno;
+
+	union {
+		int _pad[SI_PAD_SIZE32];
+
+		/* kill() */
+		struct {
+			__kernel_pid_t32 _pid;	/* sender's pid */
+			__kernel_uid_t32 _uid;	/* sender's uid */
+		} _kill;
+
+		/* SIGCHLD */
+		struct {
+			__kernel_pid_t32 _pid;	/* which child */
+			__kernel_uid_t32 _uid;	/* sender's uid */
+			int _status;		/* exit code */
+			__kernel_clock_t32 _utime;
+			__kernel_clock_t32 _stime;
+		} _sigchld;
+
+		/* IRIX SIGCHLD */
+		struct {
+			__kernel_pid_t32 _pid;	/* which child */
+			__kernel_clock_t32 _utime;
+			int _status;		/* exit code */
+			__kernel_clock_t32 _stime;
+		} _irix_sigchld;
+
+		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+		struct {
+			s32 _addr; /* faulting insn/memory ref. */
+		} _sigfault;
+
+		/* SIGPOLL, SIGXFSZ (To do ...)  */
+		struct {
+			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+			int _fd;
+		} _sigpoll;
+
+		/* POSIX.1b timers */
+		struct {
+			unsigned int _timer1;
+			unsigned int _timer2;
+		} _timer;
+
+		/* POSIX.1b signals */
+		struct {
+			__kernel_pid_t32 _pid;	/* sender's pid */
+			__kernel_uid_t32 _uid;	/* sender's uid */
+			sigval_t32 _sigval;
+		} _rt;
+
+	} _sifields;
+} siginfo_t32;
+
 struct ucontext32 {
 	u32                 uc_flags;
 	s32                 uc_link;
@@ -510,7 +575,7 @@ static inline void *get_sigframe(struct 
  	sp -= 32;
 
 	/* This is the X/Open sanctioned signal stack switching.  */
-	if ((ka->sa.sa_flags & SA_ONSTACK) && ! on_sig_stack(sp))
+	if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
 		sp = current->sas_ss_sp + current->sas_ss_size;
 
 	return (void *)((sp - frame_size) & ALMASK);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/kernel/signal_n32.c linux-2.4.29-pre3/arch/mips64/kernel/signal_n32.c
--- linux-2.4.28/arch/mips64/kernel/signal_n32.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/kernel/signal_n32.c	2004-12-22 16:06:53.534159512 +0000
@@ -138,7 +138,7 @@ static inline void *get_sigframe(struct 
  	sp -= 32;
 
 	/* This is the X/Open sanctioned signal stack switching.  */
-	if ((ka->sa.sa_flags & SA_ONSTACK) && ! on_sig_stack(sp))
+	if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
 		sp = current->sas_ss_sp + current->sas_ss_size;
 
 	return (void *)((sp - frame_size) & ALMASK);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/kernel/smp.c linux-2.4.29-pre3/arch/mips64/kernel/smp.c
--- linux-2.4.28/arch/mips64/kernel/smp.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/kernel/smp.c	2004-12-22 16:07:15.156872360 +0000
@@ -52,6 +52,9 @@ int __cpu_number_map[NR_CPUS];
 int __cpu_logical_map[NR_CPUS];
 cycles_t cacheflush_time;
 
+EXPORT_SYMBOL(__cpu_number_map);
+EXPORT_SYMBOL(__cpu_logical_map);
+
 void __init smp_callin(void)
 {
 #if 0
@@ -110,6 +113,7 @@ int smp_call_function (void (*func) (voi
 
 	spin_lock(&smp_call_lock);
 	call_data = &data;
+	wmb();
 
 	/* Send a message to all other CPUs and wait for them to respond */
 	for (i = 0; i < smp_num_cpus; i++)
@@ -283,7 +287,6 @@ void flush_tlb_page(struct vm_area_struc
 
 EXPORT_SYMBOL(smp_num_cpus);
 EXPORT_SYMBOL(flush_tlb_page);
-EXPORT_SYMBOL(cpu_data);
 EXPORT_SYMBOL(synchronize_irq);
 EXPORT_SYMBOL(kernel_flag);
 EXPORT_SYMBOL(__global_sti);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/kernel/syscall.c linux-2.4.29-pre3/arch/mips64/kernel/syscall.c
--- linux-2.4.28/arch/mips64/kernel/syscall.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/kernel/syscall.c	2004-12-22 16:07:12.597261480 +0000
@@ -34,7 +34,7 @@
 
 extern asmlinkage void syscall_trace(void);
 
-asmlinkage int sys_pipe(abi64_no_regargs, struct pt_regs regs)
+asmlinkage int sys_pipe(abi64_no_regargs, volatile struct pt_regs regs)
 {
 	int fd[2];
 	int error, res;
@@ -61,6 +61,9 @@ unsigned long arch_get_unmapped_area(str
 {
 	struct vm_area_struct * vmm;
 	int do_color_align;
+	unsigned long task_size;
+	
+	task_size = (current->thread.mflags & MF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE;
 
 	if (flags & MAP_FIXED) {
 		/*
@@ -72,7 +75,7 @@ unsigned long arch_get_unmapped_area(str
 		return addr;
 	}
 
-	if (len > TASK_SIZE)
+	if (len > task_size)
 		return -ENOMEM;
 	do_color_align = 0;
 	if (filp || (flags & MAP_SHARED))
@@ -83,7 +86,7 @@ unsigned long arch_get_unmapped_area(str
 		else
 			addr = PAGE_ALIGN(addr);
 		vmm = find_vma(current->mm, addr);
-		if (TASK_SIZE - len >= addr &&
+		if (task_size - len >= addr &&
 		    (!vmm || addr + len <= vmm->vm_start))
 			return addr;
 	}
@@ -95,7 +98,7 @@ unsigned long arch_get_unmapped_area(str
 
 	for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
 		/* At this point:  (!vmm || addr < vmm->vm_end). */
-		if (TASK_SIZE - len < addr)
+		if (task_size - len < addr)
 			return -ENOMEM;
 		if (!vmm || addr + len <= vmm->vm_start)
 			return addr;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/kernel/time.c linux-2.4.29-pre3/arch/mips64/kernel/time.c
--- linux-2.4.28/arch/mips64/kernel/time.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/kernel/time.c	2004-12-22 16:06:34.158105120 +0000
@@ -1,7 +1,7 @@
 /*
  * Copyright 2001 MontaVista Software Inc.
  * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
- * Copyright (c) 2003  Maciej W. Rozycki
+ * Copyright (c) 2003, 2004  Maciej W. Rozycki
  *
  * Common time service routines for MIPS machines. See
  * Documentation/mips/time.README.
@@ -26,6 +26,7 @@
 #include <linux/module.h>
 
 #include <asm/bootinfo.h>
+#include <asm/compiler.h>
 #include <asm/cpu.h>
 #include <asm/time.h>
 #include <asm/hardirq.h>
@@ -242,7 +243,7 @@ static unsigned long fixed_rate_gettimeo
 	__asm__("multu	%1,%2"
 		: "=h" (res)
 		: "r" (count), "r" (sll32_usecs_per_cycle)
-		: "lo", "accum");
+		: "lo", GCC_REG_ACCUM);
 
 	/*
 	 * Due to possible jiffies inconsistencies, we need to check
@@ -297,7 +298,7 @@ static unsigned long calibrate_div32_get
 	__asm__("multu  %1,%2"
 		: "=h" (res)
 		: "r" (count), "r" (quotient)
-		: "lo", "accum");
+		: "lo", GCC_REG_ACCUM);
 
 	/*
 	 * Due to possible jiffies inconsistencies, we need to check
@@ -339,7 +340,7 @@ static unsigned long calibrate_div64_get
 				: "r" (timerhi), "m" (timerlo),
 				  "r" (tmp), "r" (USECS_PER_JIFFY),
 				  "r" (USECS_PER_JIFFY_FRAC)
-				: "hi", "lo", "accum");
+				: "hi", "lo", GCC_REG_ACCUM);
 			cached_quotient = quotient;
 		}
 	}
@@ -353,7 +354,7 @@ static unsigned long calibrate_div64_get
 	__asm__("multu	%1,%2"
 		: "=h" (res)
 		: "r" (count), "r" (quotient)
-		: "lo", "accum");
+		: "lo", GCC_REG_ACCUM);
 
 	/*
 	 * Due to possible jiffies inconsistencies, we need to check
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/kernel/traps.c linux-2.4.29-pre3/arch/mips64/kernel/traps.c
--- linux-2.4.28/arch/mips64/kernel/traps.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/kernel/traps.c	2004-12-22 16:07:06.868132440 +0000
@@ -9,7 +9,7 @@
  * Copyright (C) 1999 Silicon Graphics, Inc.
  * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
  * Copyright (C) 2000, 01 MIPS Technologies, Inc.
- * Copyright (C) 2002, 2003  Maciej W. Rozycki
+ * Copyright (C) 2002, 2003, 2004  Maciej W. Rozycki
  */
 #include <linux/config.h>
 #include <linux/init.h>
@@ -22,6 +22,7 @@
 
 #include <asm/bootinfo.h>
 #include <asm/branch.h>
+#include <asm/break.h>
 #include <asm/cpu.h>
 #include <asm/fpu.h>
 #include <asm/module.h>
@@ -362,7 +363,7 @@ asmlinkage void do_be(struct pt_regs *re
 	int action = MIPS_BE_FATAL;
 
 	if (data && !user_mode(regs))
-		fixup = search_dbe_table(regs->cp0_epc);
+		fixup = search_dbe_table(exception_epc(regs));
 
 	if (fixup)
 		action = MIPS_BE_FIXUP;
@@ -606,9 +607,12 @@ asmlinkage void do_bp(struct pt_regs *re
 	/*
 	 * There is the ancient bug in the MIPS assemblers that the break
 	 * code starts left to bit 16 instead to bit 6 in the opcode.
-	 * Gas is bug-compatible ...
+	 * Gas is bug-compatible, but not always, grrr...
+	 * We handle both cases with a simple heuristics.  --macro
 	 */
-	bcode = ((opcode >> 16) & ((1 << 20) - 1));
+	bcode = ((opcode >> 6) & ((1 << 20) - 1));
+	if (bcode < (1 << 10))
+		bcode <<= 10;
 
 	/*
 	 * (A short test says that IRIX 5.3 sends SIGTRAP for all break
@@ -617,9 +621,9 @@ asmlinkage void do_bp(struct pt_regs *re
 	 * But should we continue the brokenness???  --macro
 	 */
 	switch (bcode) {
-	case 6:
-	case 7:
-		if (bcode == 7)
+	case BRK_OVERFLOW << 10:
+	case BRK_DIVZERO << 10:
+		if (bcode == (BRK_DIVZERO << 10))
 			info.si_code = FPE_INTDIV;
 		else
 			info.si_code = FPE_INTOVF;
@@ -643,7 +647,7 @@ asmlinkage void do_tr(struct pt_regs *re
 
 	/* Immediate versions don't provide a code.  */
 	if (!(opcode & OPCODE))
-		tcode = ((opcode >> 6) & ((1 << 20) - 1));
+		tcode = ((opcode >> 6) & ((1 << 10) - 1));
 
 	/*
 	 * (A short test says that IRIX 5.3 sends SIGTRAP for all trap
@@ -652,9 +656,9 @@ asmlinkage void do_tr(struct pt_regs *re
 	 * But should we continue the brokenness???  --macro
 	 */
 	switch (tcode) {
-	case 6:
-	case 7:
-		if (tcode == 7)
+	case BRK_OVERFLOW:
+	case BRK_DIVZERO:
+		if (tcode == BRK_DIVZERO)
 			info.si_code = FPE_INTDIV;
 		else
 			info.si_code = FPE_INTOVF;
@@ -851,8 +855,7 @@ void __init trap_init(void)
 		set_except_vector(i, handle_reserved);
 
 	/*
-	 * Only some CPUs have the watch exceptions or a dedicated
-	 * interrupt vector.
+	 * Only some CPUs have the watch exceptions.
 	 */
 	if (cpu_has_watch)
 		set_except_vector(23, handle_watch);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/ld.script.elf32.S linux-2.4.29-pre3/arch/mips64/ld.script.elf32.S
--- linux-2.4.28/arch/mips64/ld.script.elf32.S	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/ld.script.elf32.S	2004-12-22 16:06:38.602429480 +0000
@@ -55,6 +55,8 @@ SECTIONS
 
   .fini      : { *(.fini)    } =0
   .reginfo : { *(.reginfo) }
+  .options : { *(.options) }
+  .MIPS.options : { *(.MIPS.options) }
   /* Adjust the address for the data segment.  We want to adjust up to
      the same address within the page on the next page up.  It would
      be more correct to do this:
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/ld.script.elf64 linux-2.4.29-pre3/arch/mips64/ld.script.elf64
--- linux-2.4.28/arch/mips64/ld.script.elf64	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/ld.script.elf64	2004-12-22 16:07:31.494388680 +0000
@@ -64,6 +64,8 @@ SECTIONS
 
   .fini      : { *(.fini)    } =0
   .reginfo : { *(.reginfo) }
+  .options : { *(.options) }
+  .MIPS.options : { *(.MIPS.options) }
   /* Adjust the address for the data segment.  We want to adjust up to
      the same address within the page on the next page up.  It would
      be more correct to do this:
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/lib/dump_tlb.c linux-2.4.29-pre3/arch/mips64/lib/dump_tlb.c
--- linux-2.4.28/arch/mips64/lib/dump_tlb.c	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/lib/dump_tlb.c	2004-12-22 16:07:19.693182736 +0000
@@ -201,12 +201,10 @@ void dump16(unsigned long *p)
 {
 	int i;
 
-	for(i = 0; i < 8; i++) {
-		printk("*%08lx == %08lx, ",
-		       (unsigned long)p, (unsigned long)*p);
+	for (i = 0; i < 8; i++) {
+		printk("*%08lx == %08lx, ", (unsigned long)p, *p);
 		p++;
-		printk("*%08lx == %08lx\n",
-		       (unsigned long)p, (unsigned long)*p);
+		printk("*%08lx == %08lx\n", (unsigned long)p, *p);
 		p++;
 	}
 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/lib/strlen_user.S linux-2.4.29-pre3/arch/mips64/lib/strlen_user.S
--- linux-2.4.28/arch/mips64/lib/strlen_user.S	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/lib/strlen_user.S	2004-12-22 16:06:20.578169584 +0000
@@ -23,18 +23,18 @@
  * Return 0 for error
  */
 LEAF(__strlen_user_asm)
-	ld	v0, THREAD_CURDS($28)			# pointer ok?
-	and	v0, a0
-	bnez	v0, fault
+	LONG_L		v0, THREAD_CURDS($28)	# pointer ok?
+	and		v0, a0
+	bnez		v0, fault
 
 FEXPORT(__strlen_user_nocheck_asm)
-	move	v0, a0
-1:	EX(lb, ta0, (v0), fault)
-	daddiu	v0, 1
-	bnez	ta0, 1b
-	dsubu	v0, a0
-	jr	ra
+	move		v0, a0
+1:	EX(lb, t0, (v0), fault)
+	PTR_ADDIU	v0, 1
+	bnez		t0, 1b
+	PTR_SUBU	v0, a0
+	jr		ra
 	END(__strlen_user_asm)
 
-fault:	move	v0, zero
-	jr	ra
+fault:	move		v0, zero
+	jr		ra
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/lib/strncpy_user.S linux-2.4.29-pre3/arch/mips64/lib/strncpy_user.S
--- linux-2.4.28/arch/mips64/lib/strncpy_user.S	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/lib/strncpy_user.S	2004-12-22 16:06:01.407084032 +0000
@@ -28,31 +28,31 @@
  */
 
 LEAF(__strncpy_from_user_asm)
-	ld	v0, THREAD_CURDS($28)		# pointer ok?
-	and	v0, a1
-	bnez	v0, fault
+	LONG_L		v0, THREAD_CURDS($28)	# pointer ok?
+	and		v0, a1
+	bnez		v0, fault
 
 FEXPORT(__strncpy_from_user_nocheck_asm)
-	move	v0, zero
-	move	v1, a1
-	.set	noreorder
-1:	EX(lbu,	 ta0, (v1), fault)
-	daddiu	v1, 1
-	beqz	ta0, 2f
-	 sb	ta0, (a0)
-	daddiu	v0, 1
-	bne	v0, a2, 1b
-	 daddiu	a0, 1
-	.set	reorder
-2:	daddu	ta0, a1, v0
-	xor	ta0, a1
-	bltz	ta0, fault
-	jr	ra				# return n
+	move		v0, zero
+	move		v1, a1
+	.set		noreorder
+1:	EX(lbu, t0, (v1), fault)
+	PTR_ADDIU	v1, 1
+	beqz		t0, 2f
+	 sb		t0, (a0)
+	PTR_ADDIU	v0, 1
+	bne		v0, a2, 1b
+	 PTR_ADDIU	a0, 1
+	.set		reorder
+2:	PTR_ADDU	t0, a1, v0
+	xor		t0, a1
+	bltz		t0, fault
+	jr		ra			# return n
 	END(__strncpy_from_user_asm)
 
-fault:	li	v0, -EFAULT
-	jr	ra
+fault:	li		v0, -EFAULT
+	jr		ra
 
 	.section	__ex_table,"a"
-	PTR	1b, fault
+	PTR		1b, fault
 	.previous
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/lib/strnlen_user.S linux-2.4.29-pre3/arch/mips64/lib/strnlen_user.S
--- linux-2.4.28/arch/mips64/lib/strnlen_user.S	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/lib/strnlen_user.S	2004-12-22 16:06:21.890970008 +0000
@@ -20,23 +20,29 @@
 /*
  * Return the size of a string (including the ending 0)
  *
- * Return 0 for error, len on string but at max a1 otherwise
+ * Return 0 for error, len of string but at max a1 otherwise
+ *
+ * Note: for performance reasons we deliberately accept that a user may
+ *       make strlen_user and strnlen_user access the first few KSEG0
+ *       bytes.  There's nothing secret there ...
  */
 LEAF(__strnlen_user_asm)
-	ld	v0, THREAD_CURDS($28)	# pointer ok?
-	and	v0, a0
-	bnez	v0, fault
+	LONG_L		v0, THREAD_CURDS($28)	# pointer ok?
+	and		v0, a0
+	bnez		v0, fault
 
 FEXPORT(__strnlen_user_nocheck_asm)
-	move	v0, a0
-	daddu	a1, a0			# stop pointer
-1:	beq	v0, a1, 1f		# limit reached?
-	EX(lb, ta0, (v0), fault)
-	daddiu	v0, 1
-	bnez	ta0, 1b
-1:	dsubu	v0, a0
-	jr	ra
+	move		v0, a0
+	PTR_ADDU	a1, a0			# stop pointer
+	.set		noreorder
+1:	beq		v0, a1, 1f		# limit reached?
+	 PTR_ADDIU	v0, 1
+	.set		reorder
+	EX(lb, t0, -1(v0), fault)
+	bnez		t0, 1b
+1:	PTR_SUBU	v0, a0
+	jr		ra
 	END(__strnlen_user_asm)
 
-fault:	move	v0, zero
-	jr	ra
+fault:	move		v0, zero
+	jr		ra
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/mm/c-r4k.c linux-2.4.29-pre3/arch/mips64/mm/c-r4k.c
--- linux-2.4.28/arch/mips64/mm/c-r4k.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/mm/c-r4k.c	2004-12-22 16:05:32.110537784 +0000
@@ -42,12 +42,13 @@ static struct bcache_ops no_sc_ops = {
 
 struct bcache_ops *bcops = &no_sc_ops;
 
+#define cpu_is_r4600_v1_x()	((read_c0_prid() & 0xfffffff0) == 0x2010)
+#define cpu_is_r4600_v2_x()	((read_c0_prid() & 0xfffffff0) == 0x2020)
+
 #define R4600_HIT_CACHEOP_WAR_IMPL					\
 do {									\
-	if (R4600_V2_HIT_CACHEOP_WAR &&					\
-	    (read_c0_prid() & 0xfff0) == 0x2020) {	/* R4600 V2.0 */\
+	if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())		\
 		*(volatile unsigned long *)KSEG1;			\
-	}								\
 	if (R4600_V1_HIT_CACHEOP_WAR)					\
 		__asm__ __volatile__("nop;nop;nop;nop");		\
 } while (0)
@@ -104,6 +105,15 @@ static inline void r4k_blast_dcache_setu
 #define CACHE32_UNROLL32_ALIGN	JUMP_TO_ALIGN(10) /* 32 * 32 = 1024 */
 #define CACHE32_UNROLL32_ALIGN2	JUMP_TO_ALIGN(11)
 
+static inline void blast_r4600_v1_icache32(void)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	blast_icache32();
+	local_irq_restore(flags);
+}
+
 static inline void tx49_blast_icache32(void)
 {
 	unsigned long start = KSEG0;
@@ -125,6 +135,15 @@ static inline void tx49_blast_icache32(v
 			cache32_unroll32(addr|ws,Index_Invalidate_I);
 }
 
+static inline void blast_icache32_r4600_v1_page_indexed(unsigned long page)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	blast_icache32_page_indexed(page);
+	local_irq_restore(flags);
+}
+
 static inline void tx49_blast_icache32_page_indexed(unsigned long page)
 {
 	unsigned long start = page;
@@ -168,11 +187,17 @@ static inline void r4k_blast_icache_page
 
 	if (ic_lsize == 16)
 		r4k_blast_icache_page_indexed = blast_icache16_page_indexed;
-	else if (ic_lsize == 32 && TX49XX_ICACHE_INDEX_INV_WAR)
-		r4k_blast_icache_page_indexed = tx49_blast_icache32_page_indexed;
-	else if (ic_lsize == 32)
-		r4k_blast_icache_page_indexed = blast_icache32_page_indexed;
-	else if (ic_lsize == 64)
+	else if (ic_lsize == 32) {
+		if (TX49XX_ICACHE_INDEX_INV_WAR)
+			r4k_blast_icache_page_indexed =
+				tx49_blast_icache32_page_indexed;
+		else if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x())
+			r4k_blast_icache_page_indexed =
+				blast_icache32_r4600_v1_page_indexed;
+		else
+			r4k_blast_icache_page_indexed =
+				blast_icache32_page_indexed;
+	} else if (ic_lsize == 64)
 		r4k_blast_icache_page_indexed = blast_icache64_page_indexed;
 }
 
@@ -184,11 +209,14 @@ static inline void r4k_blast_icache_setu
 
 	if (ic_lsize == 16)
 		r4k_blast_icache = blast_icache16;
-	else if (ic_lsize == 32 && TX49XX_ICACHE_INDEX_INV_WAR)
-		r4k_blast_icache = tx49_blast_icache32;
-	else if (ic_lsize == 32)
-		r4k_blast_icache = blast_icache32;
-	else if (ic_lsize == 64)
+	else if (ic_lsize == 32) {
+		if (R4600_V1_INDEX_ICACHEOP_WAR && cpu_is_r4600_v1_x())
+			r4k_blast_icache = blast_r4600_v1_icache32;
+		else if (TX49XX_ICACHE_INDEX_INV_WAR)
+			r4k_blast_icache = tx49_blast_icache32;
+		else if (ic_lsize == 32)
+			r4k_blast_icache = blast_icache32;
+	} else if (ic_lsize == 64)
 		r4k_blast_icache = blast_icache64;
 }
 
@@ -352,6 +380,7 @@ static void r4k_flush_data_cache_page(un
 static void r4k_flush_icache_range(unsigned long start, unsigned long end)
 {
 	unsigned long dc_lsize = current_cpu_data.dcache.linesz;
+	unsigned long ic_lsize = current_cpu_data.icache.linesz;
 	unsigned long addr, aend;
 
 	if (!cpu_has_ic_fills_f_dc) {
@@ -374,14 +403,14 @@ static void r4k_flush_icache_range(unsig
 	if (end - start > icache_size)
 		r4k_blast_icache();
 	else {
-		addr = start & ~(dc_lsize - 1);
-		aend = (end - 1) & ~(dc_lsize - 1);
+		addr = start & ~(ic_lsize - 1);
+		aend = (end - 1) & ~(ic_lsize - 1);
 		while (1) {
 			/* Hit_Invalidate_I */
 			protected_flush_icache_line(addr);
 			if (addr == aend)
 				break;
-			addr += dc_lsize;
+			addr += ic_lsize;
 		}
 	}
 }
@@ -445,6 +474,9 @@ static void r4k_dma_cache_wback_inv(unsi
 {
 	unsigned long end, a;
 
+	/* Catch bad driver code */
+	BUG_ON(size == 0);
+
 	if (cpu_has_subset_pcaches) {
 		unsigned long sc_lsize = current_cpu_data.scache.linesz;
 
@@ -492,6 +524,9 @@ static void r4k_dma_cache_inv(unsigned l
 {
 	unsigned long end, a;
 
+	/* Catch bad driver code */
+	BUG_ON(size == 0);
+
 	if (cpu_has_subset_pcaches) {
 		unsigned long sc_lsize = current_cpu_data.scache.linesz;
 
@@ -754,7 +789,10 @@ static void __init probe_pcache(void)
 		c->dcache.ways = 4;
 		c->dcache.waybit = ffs(dcache_size / c->dcache.ways) - 1;
 
-		c->options |= MIPS_CPU_CACHE_CDEX_P | MIPS_CPU_PREFETCH;
+#if !defined(CONFIG_SMP) || !defined(RM9000_CDEX_SMP_WAR)
+		c->options |= MIPS_CPU_CACHE_CDEX_P;
+#endif
+		c->options |= MIPS_CPU_PREFETCH;
 		break;
 
 	default:
@@ -852,7 +890,7 @@ static void __init probe_pcache(void)
 	       cpu_has_vtag_icache ? "virtually tagged" : "physically tagged",
 	       way_string[c->icache.ways], c->icache.linesz);
 
-	printk("Primary data cache %ldkB %s, linesize %d bytes.\n",
+	printk("Primary data cache %ldkB, %s, linesize %d bytes.\n",
 	       dcache_size >> 10, way_string[c->dcache.ways], c->dcache.linesz);
 }
 
@@ -937,10 +975,8 @@ static void __init setup_scache(void)
 	 * Linux memory managment.
 	 */
 	switch (c->cputype) {
-	case CPU_R4000PC:
 	case CPU_R4000SC:
 	case CPU_R4000MC:
-	case CPU_R4400PC:
 	case CPU_R4400SC:
 	case CPU_R4400MC:
 		probe_scache_kseg1 = (probe_func_t) (KSEG1ADDR(&probe_scache));
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/mm/c-sb1.c linux-2.4.29-pre3/arch/mips64/mm/c-sb1.c
--- linux-2.4.28/arch/mips64/mm/c-sb1.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/mm/c-sb1.c	2004-12-22 16:06:03.133821528 +0000
@@ -2,6 +2,7 @@
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
  * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org)
  * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation
+ * Copyright (C) 2004  Maciej W. Rozycki
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -31,17 +32,17 @@ extern void sb1_dma_init(void);
 static unsigned long icache_size;
 static unsigned long dcache_size;
 
-static unsigned long icache_line_size;
-static unsigned long dcache_line_size;
+static unsigned short icache_line_size;
+static unsigned short dcache_line_size;
 
 static unsigned int icache_index_mask;
 static unsigned int dcache_index_mask;
 
-static unsigned long icache_assoc;
-static unsigned long dcache_assoc;
+static unsigned short icache_assoc;
+static unsigned short dcache_assoc;
 
-static unsigned int icache_sets;
-static unsigned int dcache_sets;
+static unsigned short icache_sets;
+static unsigned short dcache_sets;
 
 static unsigned int icache_range_cutoff;
 static unsigned int dcache_range_cutoff;
@@ -231,8 +232,8 @@ static void sb1_flush_cache_page(struct 
 	local_sb1_flush_cache_page(vma, addr);
 }
 #else
-void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr);
-asm("sb1_flush_cache_page = local_sb1_flush_cache_page");
+void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr)
+	__attribute__((alias("local_sb1_flush_cache_page")));
 #endif
 
 /*
@@ -280,8 +281,8 @@ static void local_sb1___flush_cache_all(
 }
 
 #ifdef CONFIG_SMP
-extern void sb1___flush_cache_all_ipi(void *ignored);
-asm("sb1___flush_cache_all_ipi = local_sb1___flush_cache_all");
+void sb1___flush_cache_all_ipi(void *ignored)
+	__attribute__((alias("local_sb1___flush_cache_all")));
 
 static void sb1___flush_cache_all(void)
 {
@@ -289,8 +290,8 @@ static void sb1___flush_cache_all(void)
 	local_sb1___flush_cache_all();
 }
 #else
-extern void sb1___flush_cache_all(void);
-asm("sb1___flush_cache_all = local_sb1___flush_cache_all");
+void sb1___flush_cache_all(void)
+	__attribute__((alias("local_sb1___flush_cache_all")));
 #endif
 
 /*
@@ -340,8 +341,8 @@ void sb1_flush_icache_range(unsigned lon
 	local_sb1_flush_icache_range(start, end);
 }
 #else
-void sb1_flush_icache_range(unsigned long start, unsigned long end);
-asm("sb1_flush_icache_range = local_sb1_flush_icache_range");
+void sb1_flush_icache_range(unsigned long start, unsigned long end)
+	__attribute__((alias("local_sb1_flush_icache_range")));
 #endif
 
 /*
@@ -398,8 +399,8 @@ static void sb1_flush_icache_page(struct
 	local_sb1_flush_icache_page(vma, page);
 }
 #else
-void sb1_flush_icache_page(struct vm_area_struct *vma, struct page *page);
-asm("sb1_flush_icache_page = local_sb1_flush_icache_page");
+void sb1_flush_icache_page(struct vm_area_struct *vma, struct page *page)
+	__attribute__((alias("local_sb1_flush_icache_page")));
 #endif
 
 /*
@@ -447,8 +448,8 @@ static void sb1_flush_cache_sigtramp(uns
 	smp_call_function(sb1_flush_cache_sigtramp_ipi, (void *) addr, 1, 1);
 }
 #else
-void sb1_flush_cache_sigtramp(unsigned long addr);
-asm("sb1_flush_cache_sigtramp = local_sb1_flush_cache_sigtramp");
+void sb1_flush_cache_sigtramp(unsigned long addr)
+	__attribute__((alias("local_sb1_flush_cache_sigtramp")));
 #endif
 
 
@@ -516,6 +517,11 @@ static unsigned int decode_cache_line_si
  * 9:7   Dcache Associativity
  */
 
+static char *way_string[] = {
+	"direct mapped", "2-way", "3-way", "4-way",
+	"5-way", "6-way", "7-way", "8-way",
+};
+
 static __init void probe_cache_sizes(void)
 {
 	u32 config1;
@@ -540,6 +546,13 @@ static __init void probe_cache_sizes(voi
 	 */
 	icache_range_cutoff = icache_sets * icache_line_size;
 	dcache_range_cutoff = (dcache_sets / 2) * icache_line_size;
+
+	printk("Primary instruction cache %ldkB, %s, linesize %d bytes.\n",
+	       icache_size >> 10, way_string[icache_assoc - 1],
+	       icache_line_size);
+	printk("Primary data cache %ldkB, %s, linesize %d bytes.\n",
+	       dcache_size >> 10, way_string[dcache_assoc - 1],
+	       dcache_line_size);
 }
 
 /*
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/mm/pg-r4k.c linux-2.4.29-pre3/arch/mips64/mm/pg-r4k.c
--- linux-2.4.28/arch/mips64/mm/pg-r4k.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/mm/pg-r4k.c	2004-12-22 16:06:54.077076976 +0000
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2003 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2003, 2004 Ralf Baechle (ralf@linux-mips.org)
  */
 #include <linux/config.h>
 #include <linux/init.h>
@@ -11,6 +11,7 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/module.h>
+#include <linux/proc_fs.h>
 
 #include <asm/cacheops.h>
 #include <asm/inst.h>
@@ -25,28 +26,30 @@
 #include <asm/cpu.h>
 #include <asm/war.h>
 
+#define half_scache_line_size()		(cpu_scache_line_size() >> 1)
+
 /*
  * Maximum sizes:
  *
- * R4000 16 bytes D-cache, 128 bytes S-cache:		0x78 bytes
- * R4600 v1.7:						0x5c bytes
- * R4600 v2.0:						0x60 bytes
- * With prefetching, 16 byte strides			0xa0 bytes
+ * R4000 128 bytes S-cache:		0x58 bytes
+ * R4600 v1.7:				0x5c bytes
+ * R4600 v2.0:				0x60 bytes
+ * With prefetching, 16 byte strides	0xa0 bytes
  */
 
-static unsigned int clear_page_array[0xa0 / 4];
+static unsigned int clear_page_array[0x130 / 4];
 
 void clear_page(void * page) __attribute__((alias("clear_page_array")));
 
 /*
  * Maximum sizes:
  *
- * R4000 16 bytes D-cache, 128 bytes S-cache:		0xbc bytes
- * R4600 v1.7:						0x80 bytes
- * R4600 v2.0:						0x84 bytes
- * With prefetching, 16 byte strides			0xb8 bytes
+ * R4000 128 bytes S-cache:		0x11c bytes
+ * R4600 v1.7:				0x080 bytes
+ * R4600 v2.0:				0x07c bytes
+ * With prefetching, 16 byte strides	0x0b8 bytes
  */
-static unsigned int copy_page_array[0xb8 / 4];
+static unsigned int copy_page_array[0x148 / 4];
 
 void copy_page(void *to, void *from) __attribute__((alias("copy_page_array")));
 
@@ -67,12 +70,58 @@ static int pref_offset_copy  __initdata 
 static unsigned int pref_src_mode __initdata;
 static unsigned int pref_dst_mode __initdata;
 
-static int has_scache __initdata = 0;
-static int load_offset __initdata = 0;
-static int store_offset __initdata = 0;
+static int load_offset __initdata;
+static int store_offset __initdata;
 
 static unsigned int __initdata *dest, *epc;
 
+static unsigned int instruction_pending;
+static union mips_instruction delayed_mi;
+
+static void __init emit_instruction(union mips_instruction mi)
+{
+	if (instruction_pending)
+		*epc++ = delayed_mi.word;
+
+	instruction_pending = 1;
+	delayed_mi = mi;
+}
+
+static inline void flush_delay_slot_or_nop(void)
+{
+	if (instruction_pending) {
+		*epc++ = delayed_mi.word;
+		instruction_pending = 0;
+		return;
+	}
+
+	*epc++ = 0;
+}
+
+static inline unsigned int *label(void)
+{
+	if (instruction_pending) {
+		*epc++ = delayed_mi.word;
+		instruction_pending = 0;
+	}
+
+	return epc;
+}
+
+static inline void build_insn_word(unsigned int word)
+{
+	union mips_instruction mi;
+
+	mi.word		 = word;
+
+	emit_instruction(mi);
+}
+
+static inline void build_nop(void)
+{
+	build_insn_word(0);			/* nop */
+}
+
 static inline void build_src_pref(int advance)
 {
 	if (!(load_offset & (cpu_dcache_line_size() - 1))) {
@@ -83,25 +132,28 @@ static inline void build_src_pref(int ad
 		mi.i_format.rt         = pref_src_mode;
 		mi.i_format.simmediate = load_offset + advance;
 
-		*epc++ = mi.word;
+		emit_instruction(mi);
 	}
 }
 
 static inline void __build_load_reg(int reg)
 {
 	union mips_instruction mi;
+	unsigned int width;
 
-	if (cpu_has_64bit_registers)
+	if (cpu_has_64bit_registers) {
 		mi.i_format.opcode     = ld_op;
-	else
+		width = 8;
+	} else {
 		mi.i_format.opcode     = lw_op;
+		width = 4;
+	}
 	mi.i_format.rs         = 5;		/* $a1 */
-	mi.i_format.rt         = reg;		/* $zero */
+	mi.i_format.rt         = reg;		/* $reg */
 	mi.i_format.simmediate = load_offset;
 
-	load_offset += (cpu_has_64bit_registers ? 8 : 4);
-
-	*epc++ = mi.word;
+	load_offset += width;
+	emit_instruction(mi);
 }
 
 static inline void build_load_reg(int reg)
@@ -122,87 +174,71 @@ static inline void build_dst_pref(int ad
 		mi.i_format.rt         = pref_dst_mode;
 		mi.i_format.simmediate = store_offset + advance;
 
-		*epc++ = mi.word;
+		emit_instruction(mi);
 	}
 }
 
-static inline void build_cdex(void)
+static inline void build_cdex_s(void)
 {
 	union mips_instruction mi;
 
-	if (cpu_has_cache_cdex_s &&
-	    !(store_offset & (cpu_scache_line_size() - 1))) {
+	if ((store_offset & (cpu_scache_line_size() - 1)))
+		return;
 
-		mi.c_format.opcode     = cache_op;
-		mi.c_format.rs         = 4;	/* $a0 */
-		mi.c_format.c_op       = 3;	/* Create Dirty Exclusive */
-		mi.c_format.cache      = 3;	/* Secondary Data Cache */
-		mi.c_format.simmediate = store_offset;
+	mi.c_format.opcode     = cache_op;
+	mi.c_format.rs         = 4;		/* $a0 */
+	mi.c_format.c_op       = 3;		/* Create Dirty Exclusive */
+	mi.c_format.cache      = 3;		/* Secondary Data Cache */
+	mi.c_format.simmediate = store_offset;
 
-		*epc++ = mi.word;
-	}
+	emit_instruction(mi);
+}
+
+static inline void build_cdex_p(void)
+{
+	union mips_instruction mi;
 
 	if (store_offset & (cpu_dcache_line_size() - 1))
 		return;
 
 	if (R4600_V1_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2010)) {
-		*epc++ = 0;			/* nop */
-		*epc++ = 0;			/* nop */
-		*epc++ = 0;			/* nop */
-		*epc++ = 0;			/* nop */
+		build_nop();
+		build_nop();
+		build_nop();
+		build_nop();
 	}
 
+	if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020))
+		build_insn_word(0x8c200000);	/* lw      $zero, ($at) */
+
 	mi.c_format.opcode     = cache_op;
 	mi.c_format.rs         = 4;		/* $a0 */
 	mi.c_format.c_op       = 3;		/* Create Dirty Exclusive */
 	mi.c_format.cache      = 1;		/* Data Cache */
 	mi.c_format.simmediate = store_offset;
 
-	*epc++ = mi.word;
+	emit_instruction(mi);
 }
 
-static inline void __build_store_zero_reg(void)
+static void __build_store_reg(int reg)
 {
 	union mips_instruction mi;
+	unsigned int width;
 
-	if (cpu_has_64bits)
+	if (cpu_has_64bit_gp_regs ||
+	    (cpu_has_64bit_zero_reg && reg == 0)) {
 		mi.i_format.opcode     = sd_op;
-	else
-		mi.i_format.opcode     = sw_op;
-	mi.i_format.rs         = 4;		/* $a0 */
-	mi.i_format.rt         = 0;		/* $zero */
-	mi.i_format.simmediate = store_offset;
-
-	store_offset += (cpu_has_64bits ? 8 : 4);
-
-	*epc++ = mi.word;
-}
-
-static inline void __build_store_reg(int reg)
-{
-	union mips_instruction mi;
-	int reg_size;
-
-#ifdef CONFIG_MIPS32
-	if (cpu_has_64bit_registers && reg == 0) {
-		mi.i_format.opcode     = sd_op;
-		reg_size               = 8;
+		width = 8;
 	} else {
 		mi.i_format.opcode     = sw_op;
-		reg_size               = 4;
+		width = 4;
 	}
-#endif
-#ifdef CONFIG_MIPS64
-	mi.i_format.opcode     = sd_op;
-	reg_size               = 8;
-#endif
 	mi.i_format.rs         = 4;		/* $a0 */
-	mi.i_format.rt         = reg;		/* $zero */
+	mi.i_format.rt         = reg;		/* $reg */
 	mi.i_format.simmediate = store_offset;
 
-	store_offset += reg_size;
-
-	*epc++ = mi.word;
+	store_offset += width;
+	emit_instruction(mi);
 }
 
 static inline void build_store_reg(int reg)
@@ -212,13 +248,15 @@ static inline void build_store_reg(int r
 			build_dst_pref(pref_offset_copy);
 		else
 			build_dst_pref(pref_offset_clear);
+	else if (cpu_has_cache_cdex_s)
+		build_cdex_s();
 	else if (cpu_has_cache_cdex_p)
-		build_cdex();
+		build_cdex_p();
 
 	__build_store_reg(reg);
 }
 
-static inline void build_addiu_at_a0(unsigned long offset)
+static inline void build_addiu_a2_a0(unsigned long offset)
 {
 	union mips_instruction mi;
 
@@ -226,10 +264,10 @@ static inline void build_addiu_at_a0(uns
 
 	mi.i_format.opcode     = cpu_has_64bit_addresses ? daddiu_op : addiu_op;
 	mi.i_format.rs         = 4;		/* $a0 */
-	mi.i_format.rt         = 1;		/* $at */
+	mi.i_format.rt         = 6;		/* $a2 */
 	mi.i_format.simmediate = offset;
 
-	*epc++ = mi.word;
+	emit_instruction(mi);
 }
 
 static inline void build_addiu_a1(unsigned long offset)
@@ -245,7 +283,7 @@ static inline void build_addiu_a1(unsign
 
 	load_offset -= offset;
 
-	*epc++ = mi.word;
+	emit_instruction(mi);
 }
 
 static inline void build_addiu_a0(unsigned long offset)
@@ -261,7 +299,7 @@ static inline void build_addiu_a0(unsign
 
 	store_offset -= offset;
 
-	*epc++ = mi.word;
+	emit_instruction(mi);
 }
 
 static inline void build_bne(unsigned int *dest)
@@ -269,16 +307,12 @@ static inline void build_bne(unsigned in
 	union mips_instruction mi;
 
 	mi.i_format.opcode = bne_op;
-	mi.i_format.rs     = 1;			/* $at */
+	mi.i_format.rs     = 6;			/* $a2 */
 	mi.i_format.rt     = 4;			/* $a0 */
 	mi.i_format.simmediate = dest - epc - 1;
 
 	*epc++ = mi.word;
-}
-
-static inline void build_nop(void)
-{
-	*epc++ = 0;
+	flush_delay_slot_or_nop();
 }
 
 static inline void build_jr_ra(void)
@@ -293,19 +327,34 @@ static inline void build_jr_ra(void)
 	mi.r_format.func   = jr_op;
 
 	*epc++ = mi.word;
+	flush_delay_slot_or_nop();
 }
 
 void __init build_clear_page(void)
 {
+	unsigned int loop_start;
+
 	epc = (unsigned int *) &clear_page_array;
+	instruction_pending = 0;
+	store_offset = 0;
 
 	if (cpu_has_prefetch) {
 		switch (current_cpu_data.cputype) {
+		case CPU_RM9000:
+			/*
+			 * As a workaround for erratum G105 which make the
+			 * PrepareForStore hint unusable we fall back to
+			 * StoreRetained on the RM9000.  Once it is known which
+			 * versions of the RM9000 we'll be able to condition-
+			 * alize this.
+			 */
+
 		case CPU_R10000:
 		case CPU_R12000:
 			pref_src_mode = Pref_LoadStreamed;
 			pref_dst_mode = Pref_StoreRetained;
 			break;
+
 		default:
 			pref_src_mode = Pref_LoadStreamed;
 			pref_dst_mode = Pref_PrepareForStore;
@@ -313,64 +362,50 @@ void __init build_clear_page(void)
 		}
 	}
 
-	build_addiu_at_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0));
+	build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0));
 
-	if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020)) {
-		*epc++ = 0x40026000;		/* mfc0    $v0, $12	*/
-		*epc++ = 0x34410001;		/* ori     $at, v0, 0x1	*/
-		*epc++ = 0x38210001;		/* xori    $at, at, 0x1	*/
-		*epc++ = 0x40816000;		/* mtc0    $at, $12	*/
-		*epc++ = 0x00000000;		/* nop			*/
-		*epc++ = 0x00000000;		/* nop			*/
-		*epc++ = 0x00000000;		/* nop			*/
-		*epc++ = 0x3c01a000;		/* lui     $at, 0xa000  */
-		*epc++ = 0x8c200000;		/* lw      $zero, ($at) */
-	}
+	if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020))
+		build_insn_word(0x3c01a000);	/* lui     $at, 0xa000  */
 
-dest = epc;
-	build_store_reg(0);
-	build_store_reg(0);
-	build_store_reg(0);
-	build_store_reg(0);
-	if (has_scache && cpu_scache_line_size() == 128) {
+dest = label();
+	do {
 		build_store_reg(0);
 		build_store_reg(0);
 		build_store_reg(0);
 		build_store_reg(0);
-	}
+	} while (store_offset < half_scache_line_size());
 	build_addiu_a0(2 * store_offset);
-	build_store_reg(0);
-	build_store_reg(0);
-	if (has_scache && cpu_scache_line_size() == 128) {
+	loop_start = store_offset;
+	do {
 		build_store_reg(0);
 		build_store_reg(0);
 		build_store_reg(0);
 		build_store_reg(0);
-	}
-	build_store_reg(0);
+	} while ((store_offset - loop_start) < half_scache_line_size());
 	build_bne(dest);
-	 build_store_reg(0);
 
 	if (cpu_has_prefetch && pref_offset_clear) {
-		build_addiu_at_a0(pref_offset_clear);
-	dest = epc;
-		__build_store_reg(0);
-		__build_store_reg(0);
-		__build_store_reg(0);
-		__build_store_reg(0);
+		build_addiu_a2_a0(pref_offset_clear);
+	dest = label();
+		loop_start = store_offset;
+		do {
+			__build_store_reg(0);
+			__build_store_reg(0);
+			__build_store_reg(0);
+			__build_store_reg(0);
+		} while ((store_offset - loop_start) < half_scache_line_size());
 		build_addiu_a0(2 * store_offset);
-		__build_store_reg(0);
-		__build_store_reg(0);
-		__build_store_reg(0);
+		loop_start = store_offset;
+		do {
+			__build_store_reg(0);
+			__build_store_reg(0);
+			__build_store_reg(0);
+			__build_store_reg(0);
+		} while ((store_offset - loop_start) < half_scache_line_size());
 		build_bne(dest);
-		 __build_store_reg(0);
 	}
 
 	build_jr_ra();
-	if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020))
-		*epc++ = 0x40826000;		/* mtc0    $v0, $12	*/
-	else
-		build_nop();
 
 	flush_icache_range((unsigned long)&clear_page_array,
 	                   (unsigned long) epc);
@@ -380,32 +415,20 @@ dest = epc;
 
 void __init build_copy_page(void)
 {
+	unsigned int loop_start;
+
 	epc = (unsigned int *) &copy_page_array;
+	store_offset = load_offset = 0;
+	instruction_pending = 0;
 
-	build_addiu_at_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0));
+	build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0));
 
-	if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020)) {
-		*epc++ = 0x40026000;		/* mfc0    $v0, $12	*/
-		*epc++ = 0x34410001;		/* ori     $at, v0, 0x1	*/
-		*epc++ = 0x38210001;		/* xori    $at, at, 0x1	*/
-		*epc++ = 0x40816000;		/* mtc0    $at, $12	*/
-		*epc++ = 0x00000000;		/* nop			*/
-		*epc++ = 0x00000000;		/* nop			*/
-		*epc++ = 0x00000000;		/* nop			*/
-		*epc++ = 0x3c01a000;		/* lui     $at, 0xa000  */
-		*epc++ = 0x8c200000;		/* lw      $zero, ($at) */
-	}
+	if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020))
+		build_insn_word(0x3c01a000);	/* lui     $at, 0xa000  */
 
-dest = epc;
-	build_load_reg( 8);
-	build_load_reg( 9);
-	build_load_reg(10);
-	build_load_reg(11);
-	build_store_reg( 8);
-	build_store_reg( 9);
-	build_store_reg(10);
-	build_store_reg(11);
-	if (has_scache && cpu_scache_line_size() == 128) {
+dest = label();
+	loop_start = store_offset;
+	do {
 		build_load_reg( 8);
 		build_load_reg( 9);
 		build_load_reg(10);
@@ -414,18 +437,11 @@ dest = epc;
 		build_store_reg( 9);
 		build_store_reg(10);
 		build_store_reg(11);
-	}
+	} while ((store_offset - loop_start) < half_scache_line_size());
 	build_addiu_a0(2 * store_offset);
 	build_addiu_a1(2 * load_offset);
-	build_load_reg( 8);
-	build_load_reg( 9);
-	build_load_reg(10);
-	build_load_reg(11);
-	build_store_reg( 8);
-	build_store_reg( 9);
-	build_store_reg(10);
-	if (has_scache && cpu_scache_line_size() == 128) {
-		build_store_reg(11);
+	loop_start = store_offset;
+	do {
 		build_load_reg( 8);
 		build_load_reg( 9);
 		build_load_reg(10);
@@ -433,39 +449,44 @@ dest = epc;
 		build_store_reg( 8);
 		build_store_reg( 9);
 		build_store_reg(10);
-	}
+		build_store_reg(11);
+	} while ((store_offset - loop_start) < half_scache_line_size());
 	build_bne(dest);
-	 build_store_reg(11);
 
 	if (cpu_has_prefetch && pref_offset_copy) {
-		build_addiu_at_a0(pref_offset_copy);
-	dest = epc;
-		__build_load_reg( 8);
-		__build_load_reg( 9);
-		__build_load_reg(10);
-		__build_load_reg(11);
-		__build_store_reg( 8);
-		__build_store_reg( 9);
-		__build_store_reg(10);
-		__build_store_reg(11);
+		build_addiu_a2_a0(pref_offset_copy);
+	dest = label();
+		loop_start = store_offset;
+		do {
+			__build_load_reg( 8);
+			__build_load_reg( 9);
+			__build_load_reg(10);
+			__build_load_reg(11);
+			__build_store_reg( 8);
+			__build_store_reg( 9);
+			__build_store_reg(10);
+			__build_store_reg(11);
+		} while ((store_offset - loop_start) < half_scache_line_size());
 		build_addiu_a0(2 * store_offset);
 		build_addiu_a1(2 * load_offset);
-		__build_load_reg( 8);
-		__build_load_reg( 9);
-		__build_load_reg(10);
-		__build_load_reg(11);
-		__build_store_reg( 8);
-		__build_store_reg( 9);
-		__build_store_reg(10);
+		loop_start = store_offset;
+		do {
+			__build_load_reg( 8);
+			__build_load_reg( 9);
+			__build_load_reg(10);
+			__build_load_reg(11);
+			__build_store_reg( 8);
+			__build_store_reg( 9);
+			__build_store_reg(10);
+			__build_store_reg(11);
+		} while ((store_offset - loop_start) < half_scache_line_size());
 		build_bne(dest);
-		 __build_store_reg(11);
 	}
 
 	build_jr_ra();
-	if (R4600_V2_HIT_CACHEOP_WAR && ((read_c0_prid() & 0xfff0) == 0x2020))
-		*epc++ = 0x40826000;		/* mtc0    $v0, $12	*/
-	else
-		build_nop();
+
+	flush_icache_range((unsigned long)&copy_page_array,
+	                   (unsigned long) epc);
 
 	BUG_ON(epc > copy_page_array + ARRAY_SIZE(copy_page_array));
 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/mm/sc-ip22.c linux-2.4.29-pre3/arch/mips64/mm/sc-ip22.c
--- linux-2.4.28/arch/mips64/mm/sc-ip22.c	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/mm/sc-ip22.c	2004-12-22 16:05:31.216673672 +0000
@@ -65,8 +65,8 @@ static void indy_sc_wback_invalidate(uns
 	printk("indy_sc_wback_invalidate[%08lx,%08lx]", addr, size);
 #endif
 
-	if (!size)
-		return;
+	/* Catch bad driver code */
+	BUG_ON(size == 0);
 
 	/* Which lines to flush?  */
 	first_line = SC_INDEX(addr);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/mm/sc-r5k.c linux-2.4.29-pre3/arch/mips64/mm/sc-r5k.c
--- linux-2.4.28/arch/mips64/mm/sc-r5k.c	2003-08-25 11:44:40.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/mm/sc-r5k.c	2004-12-22 16:07:31.494388680 +0000
@@ -47,6 +47,9 @@ static void r5k_dma_cache_inv_sc(unsigne
 {
 	unsigned long end, a;
 
+	/* Catch bad driver code */
+	BUG_ON(size == 0);
+
 	if (size >= scache_size) {
 		blast_r5000_scache();
 		return;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/mm/sc-rm7k.c linux-2.4.29-pre3/arch/mips64/mm/sc-rm7k.c
--- linux-2.4.28/arch/mips64/mm/sc-rm7k.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/mm/sc-rm7k.c	2004-12-22 16:06:42.073901736 +0000
@@ -1,8 +1,11 @@
 /*
  * sc-rm7k.c: RM7000 cache management functions.
  *
- * Copyright (C) 1997, 2001, 2003 Ralf Baechle (ralf@gnu.org),
+ * Copyright (C) 1997, 2001, 2003, 2004 Ralf Baechle (ralf@linux-mips.org)
  */
+
+#undef DEBUG
+
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
@@ -34,9 +37,10 @@ static void rm7k_sc_wback_inv(unsigned l
 {
 	unsigned long end, a;
 
-#ifdef DEBUG_CACHE
-	printk("rm7k_sc_wback_inv[%08lx,%08lx]", addr, size);
-#endif
+	pr_debug("rm7k_sc_wback_inv[%08lx,%08lx]", addr, size);
+
+	/* Catch bad driver code */
+	BUG_ON(size == 0);
 
 	a = addr & ~(sc_lsize - 1);
 	end = (addr + size - 1) & ~(sc_lsize - 1);
@@ -64,9 +68,10 @@ static void rm7k_sc_inv(unsigned long ad
 {
 	unsigned long end, a;
 
-#ifdef DEBUG_CACHE
-	printk("rm7k_sc_inv[%08lx,%08lx]", addr, size);
-#endif
+	pr_debug("rm7k_sc_inv[%08lx,%08lx]", addr, size);
+
+	/* Catch bad driver code */
+	BUG_ON(size == 0);
 
 	a = addr & ~(sc_lsize - 1);
 	end = (addr + size - 1) & ~(sc_lsize - 1);
@@ -105,16 +110,16 @@ static void rm7k_sc_inv(unsigned long ad
  *
  * It seems we get our kicks from relying on unguaranteed behaviour in GCC
  */
-static __init void rm7k_sc_enable(void)
+static __init void __rm7k_sc_enable(void)
 {
 	int i;
 
-	set_c0_config(1<<3);				/* CONF_SE */
+	set_c0_config(1 << 3);				/* CONF_SE */
 
 	write_c0_taglo(0);
 	write_c0_taghi(0);
 
-	for (i=0; i<scache_size; i+=sc_lsize) {
+	for (i = 0; i < scache_size; i += sc_lsize) {
 		__asm__ __volatile__ (
 		      ".set noreorder\n\t"
 		      ".set mips3\n\t"
@@ -122,11 +127,21 @@ static __init void rm7k_sc_enable(void)
 		      ".set mips0\n\t"
 		      ".set reorder"
 		      :
-		      : "r" (KSEG0ADDR(i)),
-		        "i" (Index_Store_Tag_SD));
+		      : "r" (KSEG0ADDR(i)), "i" (Index_Store_Tag_SD));
 	}
 }
 
+static __init void rm7k_sc_enable(void)
+{
+	void (*func)(void) = (void *) KSEG1ADDR(&__rm7k_sc_enable);
+
+	if (read_c0_config() & 0x08)			/* CONF_SE */
+		return;
+
+	printk(KERN_INFO "Enabling secondary cache...");
+	func();
+}
+
 static void rm7k_sc_disable(void)
 {
 	clear_c0_config(1<<3);				/* CONF_SE */
@@ -134,22 +149,17 @@ static void rm7k_sc_disable(void)
 
 static inline int __init rm7k_sc_probe(void)
 {
-	void (*func)(void) = KSEG1ADDR(&rm7k_sc_enable);
 	unsigned int config = read_c0_config();
 
 	if ((config >> 31) & 1)
 		return 0;
 
-	printk(KERN_INFO "Secondary cache size %ldK, linesize %ld bytes.\n",
+	printk(KERN_INFO "Secondary cache size %dK, linesize %d bytes.\n",
 	       (scache_size >> 10), sc_lsize);
 
 	if ((config >> 3) & 1)                          /* CONF_SE */
 		return 1;
 
-	printk(KERN_INFO "Enabling secondary cache...");
-	func();
-	printk("  done\n");
-
 	/*
 	 * While we're at it let's deal with the tertiary cache.
 	 */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/mm/tlb-r4k.c linux-2.4.29-pre3/arch/mips64/mm/tlb-r4k.c
--- linux-2.4.28/arch/mips64/mm/tlb-r4k.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/mm/tlb-r4k.c	2004-12-22 16:07:17.209560304 +0000
@@ -52,7 +52,7 @@ void local_flush_tlb_all(void)
 
 	local_irq_save(flags);
 	/* Save old context and create impossible VPN2 value */
-	old_ctx = (read_c0_entryhi() & ASID_MASK);
+	old_ctx = read_c0_entryhi();
 	write_c0_entryhi(XKPHYS);
 	write_c0_entrylo0(0);
 	write_c0_entrylo1(0);
@@ -103,8 +103,8 @@ void local_flush_tlb_range(struct mm_str
 		local_irq_save(flags);
 		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
 		size = (size + 1) >> 1;
-		if(size <= current_cpu_data.tlbsize/2) {
-			int oldpid = read_c0_entryhi() & ASID_MASK;
+		if (size <= current_cpu_data.tlbsize/2) {
+			int oldpid = read_c0_entryhi();
 			int newpid = cpu_asid(cpu, mm);
 
 			start &= (PAGE_MASK << 1);
@@ -151,7 +151,7 @@ void local_flush_tlb_page(struct vm_area
 		newpid = cpu_asid(cpu, vma->vm_mm);
 		page &= (PAGE_MASK << 1);
 		local_irq_save(flags);
-		oldpid = (read_c0_entryhi() & ASID_MASK);
+		oldpid = read_c0_entryhi();
 		write_c0_entryhi(page | newpid);
 		BARRIER;
 		tlb_probe();
@@ -182,7 +182,7 @@ void local_flush_tlb_one(unsigned long p
 	int oldpid, idx;
 
 	page &= (PAGE_MASK << 1);
-	oldpid = read_c0_entryhi() & ASID_MASK;
+	oldpid = read_c0_entryhi();
 
 	local_irq_save(flags);
 	write_c0_entryhi(page);
@@ -208,6 +208,7 @@ void local_flush_tlb_one(unsigned long p
 void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
 {
 	unsigned long flags;
+	unsigned int asid;
 	pgd_t *pgdp;
 	pmd_t *pmdp;
 	pte_t *ptep;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/mips64/mm/tlb-sb1.c linux-2.4.29-pre3/arch/mips64/mm/tlb-sb1.c
--- linux-2.4.28/arch/mips64/mm/tlb-sb1.c	2004-02-18 13:36:30.000000000 +0000
+++ linux-2.4.29-pre3/arch/mips64/mm/tlb-sb1.c	2004-12-22 16:06:39.376311832 +0000
@@ -118,7 +118,7 @@ void local_flush_tlb_all(void)
  * with the firmware, go back and give all the entries invalid addresses with
  * the normal flush routine.  Wired entries will be killed as well!
  */
-void sb1_sanitize_tlb(void)
+static void __init sb1_sanitize_tlb(void)
 {
 	int entry;
 	long addr = 0;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/parisc/kernel/sys_parisc32.c linux-2.4.29-pre3/arch/parisc/kernel/sys_parisc32.c
--- linux-2.4.28/arch/parisc/kernel/sys_parisc32.c	2003-06-13 14:51:31.000000000 +0000
+++ linux-2.4.29-pre3/arch/parisc/kernel/sys_parisc32.c	2004-12-22 16:06:15.845889000 +0000
@@ -1814,6 +1814,11 @@ struct cmsghdr32 {
 				    (struct cmsghdr32 *)(ctl) : \
 				    (struct cmsghdr32 *)NULL)
 #define CMSG32_FIRSTHDR(msg)	__CMSG32_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
+#define CMSG32_OK(ucmlen, ucmsg, mhdr) \
+	((ucmlen) >= sizeof(struct cmsghdr) && \
+	 (ucmlen) <= (unsigned long) \
+	 ((mhdr)->msg_controllen - \
+	  ((char *)(ucmsg) - (char *)(mhdr)->msg_control)))
 
 __inline__ struct cmsghdr32 *__cmsg32_nxthdr(void *__ctl, __kernel_size_t __size,
 					      struct cmsghdr32 *__cmsg, int __cmsg_len)
@@ -1940,11 +1945,7 @@ static int cmsghdr_from_user32_to_kern(s
 			return -EFAULT;
 
 		/* Catch bogons. */
-		if(CMSG32_ALIGN(ucmlen) <
-		   CMSG32_ALIGN(sizeof(struct cmsghdr32)))
-			return -EINVAL;
-		if((unsigned long)(((char *)ucmsg - (char *)kmsg->msg_control)
-				   + ucmlen) > kmsg->msg_controllen)
+		if (!CMSG32_OK(ucmlen, ucmsg, kmsg))
 			return -EINVAL;
 
 		tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/ppc/8xx_io/uart.c linux-2.4.29-pre3/arch/ppc/8xx_io/uart.c
--- linux-2.4.28/arch/ppc/8xx_io/uart.c	2003-11-28 18:26:19.000000000 +0000
+++ linux-2.4.29-pre3/arch/ppc/8xx_io/uart.c	2004-12-22 16:07:15.970748632 +0000
@@ -738,10 +738,7 @@ static void do_softint(void *private_)
 		return;
 
 	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup)(tty);
-		wake_up_interruptible(&tty->write_wait);
+		tty_wakeup(tty);
 	}
 }
 
@@ -1209,10 +1206,7 @@ static void rs_8xx_flush_buffer(struct t
 	/* There is nothing to "flush", whatever we gave the CPM
 	 * is on its way out.
 	 */
-	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
+	tty_wakeup(tty);
 	info->flags &= ~TX_WAKEUP;
 }
 
@@ -1760,8 +1754,8 @@ static void rs_8xx_close(struct tty_stru
 	 * the line discipline to only process XON/XOFF characters.
 	 */
 	tty->closing = 1;
-	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
-		tty_wait_until_sent(tty, info->closing_wait);
+	if (state->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, state->closing_wait);
 	/*
 	 * At this point we stop accepting input.  To do this, we
 	 * disable the receive line status interrupts, and tell the
@@ -1791,15 +1785,14 @@ static void rs_8xx_close(struct tty_stru
 	shutdown(info);
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	tty_ldisc_flush(tty);
 	tty->closing = 0;
 	info->event = 0;
 	info->tty = 0;
 	if (info->blocked_open) {
-		if (info->close_delay) {
+		if (state->close_delay) {
 			current->state = TASK_INTERRUPTIBLE;
-			schedule_timeout(info->close_delay);
+			schedule_timeout(state->close_delay);
 		}
 		wake_up_interruptible(&info->open_wait);
 	}
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/ppc/cpm2_io/uart.c linux-2.4.29-pre3/arch/ppc/cpm2_io/uart.c
--- linux-2.4.28/arch/ppc/cpm2_io/uart.c	2004-04-14 13:05:27.000000000 +0000
+++ linux-2.4.29-pre3/arch/ppc/cpm2_io/uart.c	2004-12-22 16:05:33.742289720 +0000
@@ -1754,8 +1754,8 @@ static void rs_8xx_close(struct tty_stru
 	 * the line discipline to only process XON/XOFF characters.
 	 */
 	tty->closing = 1;
-	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
-		tty_wait_until_sent(tty, info->closing_wait);
+	if (state->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, state->closing_wait);
 	/*
 	 * At this point we stop accepting input.  To do this, we
 	 * disable the receive line status interrupts, and tell the
@@ -1790,9 +1790,9 @@ static void rs_8xx_close(struct tty_stru
 	info->event = 0;
 	info->tty = 0;
 	if (info->blocked_open) {
-		if (info->close_delay) {
+		if (state->close_delay) {
 			current->state = TASK_INTERRUPTIBLE;
-			schedule_timeout(info->close_delay);
+			schedule_timeout(state->close_delay);
 		}
 		wake_up_interruptible(&info->open_wait);
 	}
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/ppc/kernel/traps.c linux-2.4.29-pre3/arch/ppc/kernel/traps.c
--- linux-2.4.28/arch/ppc/kernel/traps.c	2004-04-14 13:05:27.000000000 +0000
+++ linux-2.4.29-pre3/arch/ppc/kernel/traps.c	2004-12-22 16:05:58.088588520 +0000
@@ -88,8 +88,10 @@ void die(const char * str, struct pt_reg
 	console_verbose();
 	spin_lock_irq(&die_lock);
 #ifdef CONFIG_PMAC_BACKLIGHT
-	set_backlight_enable(1);
-	set_backlight_level(BACKLIGHT_MAX);
+	if (_machine == _MACH_Pmac) {
+		set_backlight_enable(1);
+		set_backlight_level(BACKLIGHT_MAX);
+	}
 #endif
 	printk("Oops: %s, sig: %ld\n", str, err);
 	show_regs(fp);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/ppc64/kernel/sys_ppc32.c linux-2.4.29-pre3/arch/ppc64/kernel/sys_ppc32.c
--- linux-2.4.28/arch/ppc64/kernel/sys_ppc32.c	2004-12-22 16:17:15.704575232 +0000
+++ linux-2.4.29-pre3/arch/ppc64/kernel/sys_ppc32.c	2004-12-22 16:05:53.980213088 +0000
@@ -3273,6 +3273,11 @@ asmlinkage long sys32_setsockopt(int fd,
 				    (struct cmsghdr32 *)(ctl) : \
 				    (struct cmsghdr32 *)NULL)
 #define CMSG32_FIRSTHDR(msg)	__CMSG32_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
+#define CMSG32_OK(ucmlen, ucmsg, mhdr) \
+	((ucmlen) >= sizeof(struct cmsghdr) && \
+	 (ucmlen) <= (unsigned long) \
+	 ((mhdr)->msg_controllen - \
+	  ((char *)(ucmsg) - (char *)(mhdr)->msg_control)))
 
 struct msghdr32
 {
@@ -3448,11 +3453,7 @@ static int cmsghdr_from_user32_to_kern(s
 			return -EFAULT;
 
 		/* Catch bogons. */
-		if(CMSG32_ALIGN(ucmlen) <
-		   CMSG32_ALIGN(sizeof(struct cmsghdr32)))
-			return -EINVAL;
-		if((unsigned long)(((char *)ucmsg - (char *)kmsg->msg_control)
-				   + ucmlen) > kmsg->msg_controllen)
+		if (!CMSG32_OK(ucmlen, ucmsg, kmsg))
 			return -EINVAL;
 
 		tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/s390x/kernel/exec32.c linux-2.4.29-pre3/arch/s390x/kernel/exec32.c
--- linux-2.4.28/arch/s390x/kernel/exec32.c	2001-04-12 02:02:29.000000000 +0000
+++ linux-2.4.29-pre3/arch/s390x/kernel/exec32.c	2004-12-22 16:05:31.397646160 +0000
@@ -41,7 +41,7 @@ int setup_arg_pages32(struct linux_binpr
 {
 	unsigned long stack_base;
 	struct vm_area_struct *mpnt;
-	int i;
+	int i, ret;
 
 	stack_base = STACK_TOP - MAX_ARG_PAGES*PAGE_SIZE;
 
@@ -65,7 +65,11 @@ int setup_arg_pages32(struct linux_binpr
 		mpnt->vm_pgoff = 0;
 		mpnt->vm_file = NULL;
 		mpnt->vm_private_data = (void *) 0;
-		insert_vm_struct(current->mm, mpnt);
+		if ((ret = insert_vm_struct(current->mm, mpnt))) {
+			up_write(&current->mm->mmap_sem);
+			kmem_cache_free(vm_area_cachep, mpnt);
+			return ret;
+		}
 		current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
 	} 
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/s390x/kernel/linux32.c linux-2.4.29-pre3/arch/s390x/kernel/linux32.c
--- linux-2.4.28/arch/s390x/kernel/linux32.c	2004-12-22 16:17:15.757567176 +0000
+++ linux-2.4.29-pre3/arch/s390x/kernel/linux32.c	2004-12-22 16:07:15.756781160 +0000
@@ -2306,6 +2306,11 @@ struct cmsghdr32 {
 				    (struct cmsghdr32 *)(ctl) : \
 				    (struct cmsghdr32 *)NULL)
 #define CMSG32_FIRSTHDR(msg)	__CMSG32_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
+#define CMSG32_OK(ucmlen, ucmsg, mhdr) \
+	((ucmlen) >= sizeof(struct cmsghdr) && \
+	 (ucmlen) <= (unsigned long) \
+	 ((mhdr)->msg_controllen - \
+	  ((char *)(ucmsg) - (char *)(mhdr)->msg_control)))
 
 __inline__ struct cmsghdr32 *__cmsg32_nxthdr(void *__ctl, __kernel_size_t __size,
 					      struct cmsghdr32 *__cmsg, int __cmsg_len)
@@ -2432,11 +2437,7 @@ static int cmsghdr_from_user32_to_kern(s
 			return -EFAULT;
 
 		/* Catch bogons. */
-		if(CMSG32_ALIGN(ucmlen) <
-		   CMSG32_ALIGN(sizeof(struct cmsghdr32)))
-			return -EINVAL;
-		if((unsigned long)(((char *)ucmsg - (char *)kmsg->msg_control)
-				   + ucmlen) > kmsg->msg_controllen)
+		if (!CMSG32_OK(ucmlen, ucmsg, kmsg))
 			return -EINVAL;
 
 		tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/sparc64/defconfig linux-2.4.29-pre3/arch/sparc64/defconfig
--- linux-2.4.28/arch/sparc64/defconfig	2004-12-22 16:17:15.792561856 +0000
+++ linux-2.4.29-pre3/arch/sparc64/defconfig	2004-12-22 16:06:20.970110000 +0000
@@ -415,6 +415,7 @@ CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
 # CONFIG_IDEDISK_STROKE is not set
 # CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_DELKIN is not set
 CONFIG_BLK_DEV_IDECD=y
 CONFIG_BLK_DEV_IDETAPE=m
 CONFIG_BLK_DEV_IDEFLOPPY=m
@@ -1128,6 +1129,7 @@ CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_SHA1=y
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_TWOFISH=m
@@ -1137,6 +1139,7 @@ CONFIG_CRYPTO_CAST5=m
 CONFIG_CRYPTO_CAST6=m
 CONFIG_CRYPTO_TEA=m
 CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
 CONFIG_CRYPTO_ARC4=m
 CONFIG_CRYPTO_DEFLATE=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/sparc64/kernel/binfmt_elf32.c linux-2.4.29-pre3/arch/sparc64/kernel/binfmt_elf32.c
--- linux-2.4.28/arch/sparc64/kernel/binfmt_elf32.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.29-pre3/arch/sparc64/kernel/binfmt_elf32.c	2004-12-22 16:07:32.386253096 +0000
@@ -81,7 +81,7 @@ typedef struct {
 
 #define elf_check_arch(x)	(((x)->e_machine == EM_SPARC) || ((x)->e_machine == EM_SPARC32PLUS))
 
-#define ELF_ET_DYN_BASE         0x08000000
+#define ELF_ET_DYN_BASE         0x70000000
 
 
 #include <asm/processor.h>
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/sparc64/kernel/ioctl32.c linux-2.4.29-pre3/arch/sparc64/kernel/ioctl32.c
--- linux-2.4.28/arch/sparc64/kernel/ioctl32.c	2004-12-22 16:17:15.812558816 +0000
+++ linux-2.4.29-pre3/arch/sparc64/kernel/ioctl32.c	2004-12-22 16:07:36.122685072 +0000
@@ -4928,6 +4928,7 @@ COMPATIBLE_IOCTL(RAW_SETBIND)
 COMPATIBLE_IOCTL(RAW_GETBIND)
 /* SMB ioctls which do not need any translations */
 COMPATIBLE_IOCTL(SMB_IOC_NEWCONN)
+COMPATIBLE_IOCTL(SMB_IOC_GETMOUNTUID32)
 /* NCP ioctls which do not need any translations */
 COMPATIBLE_IOCTL(NCP_IOC_CONN_LOGGED_IN)
 COMPATIBLE_IOCTL(NCP_IOC_SIGN_INIT)
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/sparc64/kernel/smp.c linux-2.4.29-pre3/arch/sparc64/kernel/smp.c
--- linux-2.4.28/arch/sparc64/kernel/smp.c	2003-11-28 18:26:19.000000000 +0000
+++ linux-2.4.29-pre3/arch/sparc64/kernel/smp.c	2004-12-22 16:05:31.129686896 +0000
@@ -137,15 +137,6 @@ extern void inherit_locked_prom_mappings
 void __init smp_callin(void)
 {
 	int cpuid = hard_smp_processor_id();
-	extern int bigkernel;
-	extern unsigned long kern_locked_tte_data;
-
-	if (bigkernel) {
-		prom_dtlb_load(sparc64_highest_locked_tlbent()-1, 
-			kern_locked_tte_data + 0x400000, KERNBASE + 0x400000);
-		prom_itlb_load(sparc64_highest_locked_tlbent()-1, 
-			kern_locked_tte_data + 0x400000, KERNBASE + 0x400000);
-	}
 
 	inherit_locked_prom_mappings(0);
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/sparc64/kernel/sys_sparc32.c linux-2.4.29-pre3/arch/sparc64/kernel/sys_sparc32.c
--- linux-2.4.28/arch/sparc64/kernel/sys_sparc32.c	2004-12-22 16:17:15.865550760 +0000
+++ linux-2.4.29-pre3/arch/sparc64/kernel/sys_sparc32.c	2004-12-22 16:07:05.438349800 +0000
@@ -2354,6 +2354,11 @@ struct cmsghdr32 {
 				    (struct cmsghdr32 *)(ctl) : \
 				    (struct cmsghdr32 *)NULL)
 #define CMSG32_FIRSTHDR(msg)	__CMSG32_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
+#define CMSG32_OK(ucmlen, ucmsg, mhdr) \
+	((ucmlen) >= sizeof(struct cmsghdr) && \
+	 (ucmlen) <= (unsigned long) \
+	 ((mhdr)->msg_controllen - \
+	  ((char *)(ucmsg) - (char *)(mhdr)->msg_control)))
 
 __inline__ struct cmsghdr32 *__cmsg32_nxthdr(void *__ctl, __kernel_size_t __size,
 					      struct cmsghdr32 *__cmsg, int __cmsg_len)
@@ -2480,11 +2485,7 @@ static int cmsghdr_from_user32_to_kern(s
 			return -EFAULT;
 
 		/* Catch bogons. */
-		if(CMSG32_ALIGN(ucmlen) <
-		   CMSG32_ALIGN(sizeof(struct cmsghdr32)))
-			return -EINVAL;
-		if((unsigned long)(((char *)ucmsg - (char *)kmsg->msg_control)
-				   + ucmlen) > kmsg->msg_controllen)
+		if (!CMSG32_OK(ucmlen, ucmsg, kmsg))
 			return -EINVAL;
 
 		tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/sparc64/kernel/trampoline.S linux-2.4.29-pre3/arch/sparc64/kernel/trampoline.S
--- linux-2.4.28/arch/sparc64/kernel/trampoline.S	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.29-pre3/arch/sparc64/kernel/trampoline.S	2004-12-22 16:06:26.582256824 +0000
@@ -90,7 +90,9 @@ startup_continue:
 	sllx		%g2, 32, %g2
 	wr		%g2, 0, %tick_cmpr
 
-	/* Call OBP by hand to lock KERNBASE into i/d tlbs. */
+	/* Call OBP by hand to lock KERNBASE into i/d tlbs.
+	 * We lock 2 consequetive entries if we are 'bigkernel'.
+	 */
 	mov		%o0, %l0
 
 	sethi		%hi(prom_entry_lock), %g2
@@ -136,6 +138,46 @@ startup_continue:
 	call		%o1
 	 add		%sp, (2047 + 128), %o0
 
+	sethi		%hi(bigkernel), %g2
+	lduw		[%g2 + %lo(bigkernel)], %g2
+	cmp		%g2, 0
+	be,pt		%icc, do_dtlb
+	 nop
+
+	sethi		%hi(call_method), %g2
+	or		%g2, %lo(call_method), %g2
+	stx		%g2, [%sp + 2047 + 128 + 0x00]
+	mov		5, %g2
+	stx		%g2, [%sp + 2047 + 128 + 0x08]
+	mov		1, %g2
+	stx		%g2, [%sp + 2047 + 128 + 0x10]
+	sethi		%hi(itlb_load), %g2
+	or		%g2, %lo(itlb_load), %g2
+	stx		%g2, [%sp + 2047 + 128 + 0x18]
+	sethi		%hi(mmu_ihandle_cache), %g2
+	lduw		[%g2 + %lo(mmu_ihandle_cache)], %g2
+	stx		%g2, [%sp + 2047 + 128 + 0x20]
+	sethi		%hi(KERNBASE + 0x400000), %g2
+	stx		%g2, [%sp + 2047 + 128 + 0x28]
+	sethi		%hi(kern_locked_tte_data), %g2
+	ldx		[%g2 + %lo(kern_locked_tte_data)], %g2
+	sethi		%hi(0x400000), %g1
+	add		%g2, %g1, %g2
+	stx		%g2, [%sp + 2047 + 128 + 0x30]
+
+	mov		14, %g2
+	BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
+
+	mov		62, %g2
+1:
+	stx		%g2, [%sp + 2047 + 128 + 0x38]
+	sethi		%hi(p1275buf), %g2
+	or		%g2, %lo(p1275buf), %g2
+	ldx		[%g2 + 0x08], %o1
+	call		%o1
+	 add		%sp, (2047 + 128), %o0
+
+do_dtlb:
 	sethi		%hi(call_method), %g2
 	or		%g2, %lo(call_method), %g2
 	stx		%g2, [%sp + 2047 + 128 + 0x00]
@@ -168,6 +210,47 @@ startup_continue:
 	call		%o1
 	 add		%sp, (2047 + 128), %o0
 
+	sethi		%hi(bigkernel), %g2
+	lduw		[%g2 + %lo(bigkernel)], %g2
+	cmp		%g2, 0
+	be,pt		%icc, do_unlock
+	 nop
+
+	sethi		%hi(call_method), %g2
+	or		%g2, %lo(call_method), %g2
+	stx		%g2, [%sp + 2047 + 128 + 0x00]
+	mov		5, %g2
+	stx		%g2, [%sp + 2047 + 128 + 0x08]
+	mov		1, %g2
+	stx		%g2, [%sp + 2047 + 128 + 0x10]
+	sethi		%hi(dtlb_load), %g2
+	or		%g2, %lo(dtlb_load), %g2
+	stx		%g2, [%sp + 2047 + 128 + 0x18]
+	sethi		%hi(mmu_ihandle_cache), %g2
+	lduw		[%g2 + %lo(mmu_ihandle_cache)], %g2
+	stx		%g2, [%sp + 2047 + 128 + 0x20]
+	sethi		%hi(KERNBASE + 0x400000), %g2
+	stx		%g2, [%sp + 2047 + 128 + 0x28]
+	sethi		%hi(kern_locked_tte_data), %g2
+	ldx		[%g2 + %lo(kern_locked_tte_data)], %g2
+	sethi		%hi(0x400000), %g1
+	add		%g2, %g1, %g2
+	stx		%g2, [%sp + 2047 + 128 + 0x30]
+
+	mov		14, %g2
+	BRANCH_IF_ANY_CHEETAH(g1,g5,1f)
+
+	mov		62, %g2
+1:
+
+	stx		%g2, [%sp + 2047 + 128 + 0x38]
+	sethi		%hi(p1275buf), %g2
+	or		%g2, %lo(p1275buf), %g2
+	ldx		[%g2 + 0x08], %o1
+	call		%o1
+	 add		%sp, (2047 + 128), %o0
+
+do_unlock:
 	sethi		%hi(prom_entry_lock), %g2
 	stb		%g0, [%g2 + %lo(prom_entry_lock)]
 	membar		#StoreStore | #StoreLoad
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/x86_64/ia32/ia32_binfmt.c linux-2.4.29-pre3/arch/x86_64/ia32/ia32_binfmt.c
--- linux-2.4.28/arch/x86_64/ia32/ia32_binfmt.c	2003-11-28 18:26:19.000000000 +0000
+++ linux-2.4.29-pre3/arch/x86_64/ia32/ia32_binfmt.c	2004-12-22 16:05:32.903417248 +0000
@@ -225,7 +225,7 @@ int ia32_setup_arg_pages(struct linux_bi
 {
 	unsigned long stack_base;
 	struct vm_area_struct *mpnt;
-	int i;
+	int i, ret;
 
 	stack_base = IA32_STACK_TOP - MAX_ARG_PAGES*PAGE_SIZE;
 
@@ -250,7 +250,11 @@ int ia32_setup_arg_pages(struct linux_bi
 		mpnt->vm_pgoff = 0;
 		mpnt->vm_file = NULL;
 		mpnt->vm_private_data = (void *) 0;
-		insert_vm_struct(current->mm, mpnt);
+		if ((ret = insert_vm_struct(current->mm, mpnt))) {
+			up_write(&current->mm->mmap_sem);
+			kmem_cache_free(vm_area_cachep, mpnt);
+			return ret;
+		}
 		current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
 	} 
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/x86_64/ia32/ia32entry.S linux-2.4.29-pre3/arch/x86_64/ia32/ia32entry.S
--- linux-2.4.28/arch/x86_64/ia32/ia32entry.S	2004-08-07 23:26:04.000000000 +0000
+++ linux-2.4.29-pre3/arch/x86_64/ia32/ia32entry.S	2004-12-22 16:06:00.677194992 +0000
@@ -52,6 +52,7 @@ ENTRY(ia32_cstar_target)
 ENTRY(ia32_syscall)
 	swapgs	
 	sti
+	movl %eax,%eax	
 	pushq %rax
 	cld
 	SAVE_ARGS
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/x86_64/ia32/socket32.c linux-2.4.29-pre3/arch/x86_64/ia32/socket32.c
--- linux-2.4.28/arch/x86_64/ia32/socket32.c	2004-12-22 16:17:15.953537384 +0000
+++ linux-2.4.29-pre3/arch/x86_64/ia32/socket32.c	2004-12-22 16:05:54.007208984 +0000
@@ -136,12 +136,9 @@ static int cmsghdr_from_user32_to_kern(s
 			return -EFAULT;
 
 		/* Catch bogons. */
-		if(CMSG32_ALIGN(ucmlen) <
-		   CMSG32_ALIGN(sizeof(struct cmsghdr32)))
-			return -EINVAL;
-		if((unsigned long)(((char *)ucmsg - (char *)kmsg->msg_control)
-				   + ucmlen) > kmsg->msg_controllen)
+		if (!CMSG32_OK(ucmlen, ucmsg, kmsg))
 			return -EINVAL;
+
 		if (kmsg->msg_controllen > 65536) 
 			return -EINVAL;
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/x86_64/ia32/sys_ia32.c linux-2.4.29-pre3/arch/x86_64/ia32/sys_ia32.c
--- linux-2.4.28/arch/x86_64/ia32/sys_ia32.c	2004-12-22 16:17:15.961536168 +0000
+++ linux-2.4.29-pre3/arch/x86_64/ia32/sys_ia32.c	2004-12-22 16:07:33.035154448 +0000
@@ -2214,7 +2214,7 @@ static int nargs(u32 src, char **dst) 
 			dst[cnt] = (char *)(u64)val; 
 		cnt++;
 		src += 4;
-		if (cnt >= (MAX_ARG_PAGES*PAGE_SIZE)/sizeof(void*))
+		if (cnt >= (MAX_ARG_PAGES * PAGE_SIZE) / sizeof(char *))
 			return -E2BIG; 
 	} while(val); 
 	if (dst)
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/x86_64/kernel/setup.c linux-2.4.29-pre3/arch/x86_64/kernel/setup.c
--- linux-2.4.28/arch/x86_64/kernel/setup.c	2004-08-07 23:26:04.000000000 +0000
+++ linux-2.4.29-pre3/arch/x86_64/kernel/setup.c	2004-12-22 16:05:55.996906504 +0000
@@ -52,6 +52,7 @@ int acpi_disabled;
 EXPORT_SYMBOL(acpi_disabled);
 
 int swiotlb;
+EXPORT_SYMBOL(swiotlb);
 
 extern	int phys_proc_id[NR_CPUS];
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/arch/x86_64/kernel/signal.c linux-2.4.29-pre3/arch/x86_64/kernel/signal.c
--- linux-2.4.28/arch/x86_64/kernel/signal.c	2003-11-28 18:26:19.000000000 +0000
+++ linux-2.4.29-pre3/arch/x86_64/kernel/signal.c	2004-12-22 16:07:10.761540552 +0000
@@ -561,7 +561,7 @@ int do_signal(struct pt_regs *regs, sigs
 	}
 
 	/* Did we come from a system call? */
-	if (regs->orig_rax >= 0) {
+	if ((long)regs->orig_rax >= 0) {
 		/* Restart the system call - no handlers present */
 		if (regs->rax == -ERESTARTNOHAND ||
 		    regs->rax == -ERESTARTSYS ||
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/acpi/bus.c linux-2.4.29-pre3/drivers/acpi/bus.c
--- linux-2.4.28/drivers/acpi/bus.c	2004-12-22 16:17:16.089516712 +0000
+++ linux-2.4.29-pre3/drivers/acpi/bus.c	2004-12-22 16:06:56.702677824 +0000
@@ -1850,7 +1850,10 @@ acpi_early_init (void)
 	acpi_status		status = AE_OK;
 	struct acpi_buffer	buffer = {sizeof(acpi_fadt), &acpi_fadt};
 
-	ACPI_FUNCTION_TRACE("acpi_bus_init");
+	ACPI_FUNCTION_TRACE("acpi_early_init");
+
+	if (acpi_disabled)
+		return_VOID;
 
 	status = acpi_initialize_subsystem();
 	if (ACPI_FAILURE(status)) {
@@ -1899,11 +1902,11 @@ acpi_early_init (void)
 		goto error0;
 	}
 
-	return;
+	return_VOID;
 
 error0:
 	disable_acpi();
-	return;
+	return_VOID;
 }
 
 static int __init
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/acpi/motherboard.c linux-2.4.29-pre3/drivers/acpi/motherboard.c
--- linux-2.4.28/drivers/acpi/motherboard.c	2004-12-22 16:17:16.106514128 +0000
+++ linux-2.4.29-pre3/drivers/acpi/motherboard.c	2004-12-22 16:07:22.617738136 +0000
@@ -17,6 +17,8 @@
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  */
 
+/* Purpose: Prevent PCMCIA cards from using motherboard resources. */
+
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/types.h>
@@ -43,9 +45,17 @@ ACPI_MODULE_NAME		("acpi_motherboard")
 	(((len) > 0) && ((base) > 0) && ((base) + (len) < IO_SPACE_LIMIT) \
 	&& ((base) + (len) > PCIBIOS_MIN_IO))
 
+/*
+ * Clearing the flag (IORESOURCE_BUSY) allows drivers to use
+ * the io ports if they really know they can use it, while
+ * still preventing hotplug PCI devices from using it. 
+ */
+
 static acpi_status
 acpi_reserve_io_ranges (struct acpi_resource *res, void *data)
 {
+	struct resource *requested_res = NULL;
+
 	ACPI_FUNCTION_TRACE("acpi_reserve_io_ranges");
 
 	if (res->id == ACPI_RSTYPE_IO) {
@@ -57,23 +67,25 @@ acpi_reserve_io_ranges (struct acpi_reso
 			ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Motherboard resources 0x%08x - 0x%08x\n",
 				io_res->min_base_address, 
 				io_res->min_base_address + io_res->range_length));
-			request_region(io_res->min_base_address, 
+			requested_res = request_region(io_res->min_base_address, 
 				io_res->range_length, "motherboard");
 		}
-	}else if (res->id == ACPI_RSTYPE_FIXED_IO) {
+	} else if (res->id == ACPI_RSTYPE_FIXED_IO) {
 		struct acpi_resource_fixed_io *fixed_io_res = &res->data.fixed_io;
 
 		if (IS_RESERVED_ADDR(fixed_io_res->base_address, fixed_io_res->range_length)) {
 			ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Motherboard resources 0x%08x - 0x%08x\n",
 				fixed_io_res->base_address, 
 				fixed_io_res->base_address + fixed_io_res->range_length));
-			request_region(fixed_io_res->base_address, 
+			requested_res = request_region(fixed_io_res->base_address, 
 				fixed_io_res->range_length, "motherboard");
 		}
-	}else {
+	} else {
 		/* Memory mapped IO? */
 	}
 
+	if (requested_res)
+		requested_res->flags &= ~IORESOURCE_BUSY;
 	return AE_OK;
 }
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/atm/Makefile linux-2.4.29-pre3/drivers/atm/Makefile
--- linux-2.4.28/drivers/atm/Makefile	2003-11-28 18:26:19.000000000 +0000
+++ linux-2.4.29-pre3/drivers/atm/Makefile	2004-12-22 16:05:32.474482456 +0000
@@ -92,7 +92,7 @@ fore200e_mkfirm: fore200e_mkfirm.c
 # deal with the various suffixes of the binary firmware images
 %.bin %.bin1 %.bin2: %.data
 	objcopy -Iihex $< -Obinary $@.gz
-	gzip -df $@.gz
+	gzip -n -df $@.gz
 
 fore_200e.o: $(fore_200e-objs)
 	$(LD) -r -o $@ $(fore_200e-objs)
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/block/DAC960.c linux-2.4.29-pre3/drivers/block/DAC960.c
--- linux-2.4.28/drivers/block/DAC960.c	2002-11-28 23:53:12.000000000 +0000
+++ linux-2.4.29-pre3/drivers/block/DAC960.c	2004-12-22 16:07:19.663187296 +0000
@@ -1133,6 +1133,26 @@ static boolean DAC960_V1_ReadControllerC
     DAC960PU/PD/PL	    3.51 and above
     DAC960PU/PD/PL/P	    2.73 and above
   */
+#if defined(__alpha__)
+  /*
+    DEC Alpha machines were often equipped with DAC960 cards that were
+    OEMed from Mylex, and had their own custom firmware. Version 2.70,
+    the last custom FW revision to be released by DEC for these older
+    controllers, appears to work quite well with this driver.
+
+    Cards tested successfully were several versions each of the PD and
+    PU, called by DEC the KZPSC and KZPAC, respectively, and having
+    the Manufacturer Numbers (from Mylex), usually on a sticker on the
+    back of the board, of:
+
+    KZPSC	D040347 (1ch) or D040348 (2ch) or D040349 (3ch)
+    KZPAC	D040395 (1ch) or D040396 (2ch) or D040397 (3ch)
+  */
+# define FIRMWARE_27x "2.70"
+#else
+# define FIRMWARE_27x "2.73"
+#endif
+
   if (Enquiry2.FirmwareID.MajorVersion == 0)
     {
       Enquiry2.FirmwareID.MajorVersion =
@@ -1152,7 +1172,7 @@ static boolean DAC960_V1_ReadControllerC
 	(Controller->FirmwareVersion[0] == '3' &&
 	 strcmp(Controller->FirmwareVersion, "3.51") >= 0) ||
 	(Controller->FirmwareVersion[0] == '2' &&
-	 strcmp(Controller->FirmwareVersion, "2.73") >= 0)))
+	 strcmp(Controller->FirmwareVersion, FIRMWARE_27x) >= 0)))
     {
       DAC960_Failure(Controller, "FIRMWARE VERSION VERIFICATION");
       DAC960_Error("Firmware Version = '%s'\n", Controller,
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/block/floppy.c linux-2.4.29-pre3/drivers/block/floppy.c
--- linux-2.4.28/drivers/block/floppy.c	2003-08-25 11:44:41.000000000 +0000
+++ linux-2.4.29-pre3/drivers/block/floppy.c	2004-12-22 16:05:50.431752536 +0000
@@ -4255,6 +4255,14 @@ int __init floppy_init(void)
 		max_buffer_sectors = 0;
 	}
 
+	/*
+	 * Small 10 msec delay to let through any interrupt that
+	 * initialization might have triggered, to not
+	 * confuse detection:
+	 */
+	current->state = TASK_UNINTERRUPTIBLE;
+	schedule_timeout(HZ/100 + 1);
+
 	for (i = 0; i < N_FDC; i++) {
 		fdc = i;
 		FDCS->driver_version = FD_DRIVER_VERSION;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/block/sx8.c linux-2.4.29-pre3/drivers/block/sx8.c
--- linux-2.4.28/drivers/block/sx8.c	2004-08-07 23:26:04.000000000 +0000
+++ linux-2.4.29-pre3/drivers/block/sx8.c	2004-12-22 16:06:16.775747640 +0000
@@ -548,17 +548,6 @@ static int carm_bdev_ioctl(struct inode 
 	return -EOPNOTSUPP;
 }
 
-static inline unsigned long msecs_to_jiffies(unsigned long msecs)
-{
-	return ((HZ * msecs + 999) / 1000);
-}
-
-static void msleep(unsigned long msecs)
-{
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(msecs_to_jiffies(msecs) + 1);
-}
-
 static const u32 msg_sizes[] = { 32, 64, 128, CARM_MSG_SIZE };
 
 static inline int carm_lookup_bucket(u32 msg_size)
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/bluetooth/hci_ldisc.c linux-2.4.29-pre3/drivers/bluetooth/hci_ldisc.c
--- linux-2.4.28/drivers/bluetooth/hci_ldisc.c	2004-08-07 23:26:04.000000000 +0000
+++ linux-2.4.29-pre3/drivers/bluetooth/hci_ldisc.c	2004-12-22 16:07:34.060998496 +0000
@@ -188,9 +188,7 @@ static int hci_uart_flush(struct hci_dev
 		kfree_skb(hu->tx_skb); hu->tx_skb = NULL;
 	}
 
-	/* Flush any pending characters in the driver and discipline. */
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	tty_ldisc_flush(tty);
 
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
@@ -283,9 +281,10 @@ static int hci_uart_tty_open(struct tty_
 
 	spin_lock_init(&hu->rx_lock);
 
-	/* Flush any pending characters in the driver and line discipline */
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	/* Flush any pending characters in the driver and line discipline. */
+	/* FIXME: why is this needed. Note don't use ldisc_ref here as the
+	   open path is before the ldisc is referencable */
+	tty_ldisc_flush(tty);
 
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/cdrom/cdrom.c linux-2.4.29-pre3/drivers/cdrom/cdrom.c
--- linux-2.4.28/drivers/cdrom/cdrom.c	2003-11-28 18:26:20.000000000 +0000
+++ linux-2.4.29-pre3/drivers/cdrom/cdrom.c	2004-12-22 16:05:50.454749040 +0000
@@ -2598,9 +2598,7 @@ ctl_table cdrom_cdrom_table[] = {
 
 /* Make sure that /proc/sys/dev is there */
 ctl_table cdrom_root_table[] = {
-#ifdef CONFIG_PROC_FS
 	{CTL_DEV, "dev", NULL, 0, 0555, cdrom_cdrom_table},
-#endif /* CONFIG_PROC_FS */
 	{0}
 	};
 static struct ctl_table_header *cdrom_sysctl_header;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/amiserial.c linux-2.4.29-pre3/drivers/char/amiserial.c
--- linux-2.4.28/drivers/char/amiserial.c	2002-11-28 23:53:12.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/amiserial.c	2004-12-22 16:07:53.395059272 +0000
@@ -575,10 +575,7 @@ static void do_softint(void *private_)
 		return;
 
 	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup)(tty);
-		wake_up_interruptible(&tty->write_wait);
+		tty_wakeup(tty);
 	}
 }
 
@@ -1040,10 +1037,7 @@ static void rs_flush_buffer(struct tty_s
 	save_flags(flags); cli();
 	info->xmit.head = info->xmit.tail = 0;
 	restore_flags(flags);
-	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
+	tty_wakeup(tty);
 }
 
 /*
@@ -1581,8 +1575,8 @@ static void rs_close(struct tty_struct *
 	 * the line discipline to only process XON/XOFF characters.
 	 */
 	tty->closing = 1;
-	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
-		tty_wait_until_sent(tty, info->closing_wait);
+	if (state->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, state->closing_wait);
 	/*
 	 * At this point we stop accepting input.  To do this, we
 	 * disable the receive line status interrupts, and tell the
@@ -1608,15 +1602,14 @@ static void rs_close(struct tty_struct *
 	shutdown(info);
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	tty_ldisc_flush(tty);
 	tty->closing = 0;
 	info->event = 0;
 	info->tty = 0;
 	if (info->blocked_open) {
-		if (info->close_delay) {
+		if (state->close_delay) {
 			current->state = TASK_INTERRUPTIBLE;
-			schedule_timeout(info->close_delay);
+			schedule_timeout(state->close_delay);
 		}
 		wake_up_interruptible(&info->open_wait);
 	}
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/au1x00-serial.c linux-2.4.29-pre3/drivers/char/au1x00-serial.c
--- linux-2.4.28/drivers/char/au1x00-serial.c	2003-08-25 11:44:41.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/au1x00-serial.c	2004-12-22 16:06:16.798744144 +0000
@@ -1948,8 +1948,8 @@ static void rs_close(struct tty_struct *
 	 * the line discipline to only process XON/XOFF characters.
 	 */
 	tty->closing = 1;
-	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
-		tty_wait_until_sent(tty, info->closing_wait);
+	if (state->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, state->closing_wait);
 	/*
 	 * At this point we stop accepting input.  To do this, we
 	 * disable the receive line status interrupts, and tell the
@@ -1976,9 +1976,9 @@ static void rs_close(struct tty_struct *
 	info->event = 0;
 	info->tty = 0;
 	if (info->blocked_open) {
-		if (info->close_delay) {
+		if (state->close_delay) {
 			set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout(info->close_delay);
+			schedule_timeout(state->close_delay);
 		}
 		wake_up_interruptible(&info->open_wait);
 	}
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/console.c linux-2.4.29-pre3/drivers/char/console.c
--- linux-2.4.28/drivers/char/console.c	2003-11-28 18:26:20.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/console.c	2004-12-22 16:07:31.897327424 +0000
@@ -705,6 +705,9 @@ int vc_allocate(unsigned int currcons)	/
 	return 0;
 }
 
+#define VC_RESIZE_MAXCOL (32767)
+#define VC_RESIZE_MAXROW (32767)
+
 /*
  * Change # of rows and columns (0 means unchanged/the size of fg_console)
  * [this is to be used together with some user program
@@ -717,6 +720,9 @@ int vc_resize(unsigned int lines, unsign
 	unsigned int currcons = fg_console, i;
 	unsigned short *newscreens[MAX_NR_CONSOLES];
 
+	if (cols > VC_RESIZE_MAXCOL || lines > VC_RESIZE_MAXROW)
+		return -EINVAL;
+
 	cc = (cols ? cols : video_num_columns);
 	ll = (lines ? lines : video_num_lines);
 	sr = cc << 1;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/cyclades.c linux-2.4.29-pre3/drivers/char/cyclades.c
--- linux-2.4.28/drivers/char/cyclades.c	2003-06-13 14:51:32.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/cyclades.c	2004-12-22 16:05:58.772484552 +0000
@@ -1000,11 +1000,7 @@ do_softint(void *private_)
 	wake_up_interruptible(&info->delta_msr_wait);
     }
     if (test_and_clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) {
-        if((tty->flags & (1<< TTY_DO_WRITE_WAKEUP))
-        && tty->ldisc.write_wakeup){
-            (tty->ldisc.write_wakeup)(tty);
-        }
-        wake_up_interruptible(&tty->write_wait);
+	tty_wakeup(tty);
     }
 #ifdef Z_WAKE
     if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event)) {
@@ -2918,8 +2914,7 @@ cy_close(struct tty_struct *tty, struct 
     shutdown(info);
     if (tty->driver.flush_buffer)
         tty->driver.flush_buffer(tty);
-    if (tty->ldisc.flush_buffer)
-        tty->ldisc.flush_buffer(tty);
+    tty_ldisc_flush(tty);
     CY_LOCK(info, flags);
 
     tty->closing = 0;
@@ -4689,10 +4684,7 @@ cy_flush_buffer(struct tty_struct *tty)
 	}
 	CY_UNLOCK(info, flags);
     }
-    wake_up_interruptible(&tty->write_wait);
-    if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP))
-	&& tty->ldisc.write_wakeup)
-	    (tty->ldisc.write_wakeup)(tty);
+    tty_wakeup(tty);
 } /* cy_flush_buffer */
 
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/dz.c linux-2.4.29-pre3/drivers/char/dz.c
--- linux-2.4.28/drivers/char/dz.c	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/dz.c	2004-12-22 16:05:36.044939664 +0000
@@ -402,9 +402,7 @@ static void do_softint(void *private_dat
 		return;
 
 	if (test_and_clear_bit(DZ_EVENT_WRITE_WAKEUP, &info->event)) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup) (tty);
-		wake_up_interruptible(&tty->write_wait);
+		tty_wakeup(tty);
 	}
 }
 
@@ -804,10 +802,7 @@ static void dz_flush_buffer(struct tty_s
 	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
 	sti();
 
-	wake_up_interruptible(&tty->write_wait);
-
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup) (tty);
+	tty_wakeup(tty);
 }
 
 /*
@@ -1106,16 +1101,15 @@ static void dz_close(struct tty_struct *
 
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	tty_ldisc_flush(tty);
 	tty->closing = 0;
 	info->event = 0;
 	info->tty = 0;
 
-	if (tty->ldisc.num != ldiscs[N_TTY].num) {
+	if (tty->ldisc.num != N_TTY) {
 		if (tty->ldisc.close)
 			(tty->ldisc.close) (tty);
-		tty->ldisc = ldiscs[N_TTY];
+		tty->ldisc = *(tty_ldisc_get(N_TTY));
 		tty->termios->c_line = N_TTY;
 		if (tty->ldisc.open)
 			(tty->ldisc.open) (tty);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/epca.c linux-2.4.29-pre3/drivers/char/epca.c
--- linux-2.4.28/drivers/char/epca.c	2003-06-13 14:51:33.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/epca.c	2004-12-22 16:07:00.201145976 +0000
@@ -585,9 +585,7 @@ static void pc_close(struct tty_struct *
 		if (tty->driver.flush_buffer)
 			tty->driver.flush_buffer(tty);
 
-		if (tty->ldisc.flush_buffer)
-			tty->ldisc.flush_buffer(tty);
-
+		tty_ldisc_flush(tty);
 		shutdown(ch);
 		tty->closing = 0;
 		ch->event = 0;
@@ -692,15 +690,13 @@ static void pc_hangup(struct tty_struct 
 		cli();
 		if (tty->driver.flush_buffer)
 			tty->driver.flush_buffer(tty);
-
-		if (tty->ldisc.flush_buffer)
-			tty->ldisc.flush_buffer(tty);
-
+		
+		tty_ldisc_flush(tty);
+		
 		shutdown(ch);
 
 		if (ch->count)
 			MOD_DEC_USE_COUNT;
-		
 
 		ch->tty   = NULL;
 		ch->event = 0;
@@ -1175,9 +1171,7 @@ static void pc_flush_buffer(struct tty_s
 	memoff(ch);
 	restore_flags(flags);
 
-	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
+	tty_wakeup(tty);
 
 } /* End pc_flush_buffer */
 
@@ -2383,10 +2377,7 @@ static void doevent(int crd)
 				{ /* Begin if LOWWAIT */
 
 					ch->statusflags &= ~LOWWAIT;
-					if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-						  tty->ldisc.write_wakeup)
-						(tty->ldisc.write_wakeup)(tty);
-					wake_up_interruptible(&tty->write_wait);
+					tty_wakeup(tty);
 
 				} /* End if LOWWAIT */
 
@@ -2402,11 +2393,7 @@ static void doevent(int crd)
 				{ /* Begin if EMPTYWAIT */
 
 					ch->statusflags &= ~EMPTYWAIT;
-					if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-						  tty->ldisc.write_wakeup)
-						(tty->ldisc.write_wakeup)(tty);
-
-					wake_up_interruptible(&tty->write_wait);
+					tty_wakeup(tty);
 
 				} /* End if EMPTYWAIT */
 
@@ -3255,8 +3242,8 @@ static int pc_ioctl(struct tty_struct *t
 			}
 			else 
 			{
-				if (tty->ldisc.flush_buffer)
-					tty->ldisc.flush_buffer(tty);
+				/* ldisc lock already held in ioctl */
+				tty_ldisc_flush(tty);
 			}
 
 			/* Fall Thru */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/esp.c linux-2.4.29-pre3/drivers/char/esp.c
--- linux-2.4.28/drivers/char/esp.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/esp.c	2004-12-22 16:05:31.465635824 +0000
@@ -786,10 +786,7 @@ static void do_softint(void *private_)
 		return;
 
 	if (test_and_clear_bit(ESP_EVENT_WRITE_WAKEUP, &info->event)) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup)(tty);
-		wake_up_interruptible(&tty->write_wait);
+		tty_wakeup(tty);
 	}
 }
 
@@ -1395,10 +1392,7 @@ static void rs_flush_buffer(struct tty_s
 	cli();
 	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
 	sti();
-	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
+	tty_wakeup(tty);
 }
 
 /*
@@ -2115,8 +2109,7 @@ static void rs_close(struct tty_struct *
 	shutdown(info);
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	tty_ldisc_flush(tty);
 	tty->closing = 0;
 	info->event = 0;
 	info->tty = 0;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/generic_serial.c linux-2.4.29-pre3/drivers/char/generic_serial.c
--- linux-2.4.28/drivers/char/generic_serial.c	2002-11-28 23:53:12.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/generic_serial.c	2004-12-22 16:06:46.588215456 +0000
@@ -439,10 +439,7 @@ void gs_flush_buffer(struct tty_struct *
 	port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
 	restore_flags(flags);
 
-	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
+	tty_wakeup(tty);
 	func_exit ();
 }
 
@@ -582,10 +579,7 @@ void gs_do_softint(void *private_)
 	if (!tty) return;
 
 	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup)(tty);
-		wake_up_interruptible(&tty->write_wait);
+		tty_wakeup(tty);
 	}
 	func_exit ();
 }
@@ -729,8 +723,8 @@ void gs_close(struct tty_struct * tty, s
 {
 	unsigned long flags;
 	struct gs_port *port;
-
-	func_enter ();
+	
+	func_enter();
 
 	if (!tty) return;
 
@@ -803,8 +797,7 @@ void gs_close(struct tty_struct * tty, s
 
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	tty_ldisc_flush(tty);
 	tty->closing = 0;
 
 	port->event = 0;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/hvc_console.c linux-2.4.29-pre3/drivers/char/hvc_console.c
--- linux-2.4.28/drivers/char/hvc_console.c	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/hvc_console.c	2004-12-22 16:06:16.414802512 +0000
@@ -217,10 +217,7 @@ static void hvc_poll(int index)
 
 		if (hp->do_wakeup) {
 			hp->do_wakeup = 0;
-			if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP))
-			    && tty->ldisc.write_wakeup)
-				(tty->ldisc.write_wakeup)(tty);
-			wake_up_interruptible(&tty->write_wait);
+			tty_wakeup(tty);
 		}
 	}
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/ip2/i2lib.c linux-2.4.29-pre3/drivers/char/ip2/i2lib.c
--- linux-2.4.28/drivers/char/ip2/i2lib.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/ip2/i2lib.c	2004-12-22 16:07:51.807300648 +0000
@@ -1385,15 +1385,9 @@ ip2_owake( PTTY tp)
 	ip2trace (CHANN, ITRC_SICMD, 10, 2, tp->flags,
 			(1 << TTY_DO_WRITE_WAKEUP) );
 
-	wake_up_interruptible ( &tp->write_wait );
-	if ( ( tp->flags & (1 << TTY_DO_WRITE_WAKEUP) ) 
-	  && tp->ldisc.write_wakeup )
-	{
-		(tp->ldisc.write_wakeup) ( tp );
-
-		ip2trace (CHANN, ITRC_SICMD, 11, 0 );
+	tty_wakeup(tp);
+	ip2trace (CHANN, ITRC_SICMD, 11, 0 );
 
-	}
 }
 
 static inline void
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/ip2main.c linux-2.4.29-pre3/drivers/char/ip2main.c
--- linux-2.4.28/drivers/char/ip2main.c	2004-12-22 16:17:16.228495584 +0000
+++ linux-2.4.29-pre3/drivers/char/ip2main.c	2004-12-22 16:07:55.566729128 +0000
@@ -1462,8 +1462,7 @@ isig(int sig, struct tty_struct *tty, in
 	if (tty->pgrp > 0)
 		kill_pg(tty->pgrp, sig, 1);
 	if (flush || !L_NOFLSH(tty)) {
-		if ( tty->ldisc.flush_buffer )  
-			tty->ldisc.flush_buffer(tty);
+		tty_ldisc_flush(tty);
 		i2InputFlush( tty->driver_data );
 	}
 }
@@ -1853,8 +1852,7 @@ ip2_close( PTTY tty, struct file *pFile 
 
 	if ( tty->driver.flush_buffer ) 
 		tty->driver.flush_buffer(tty);
-	if ( tty->ldisc.flush_buffer )  
-		tty->ldisc.flush_buffer(tty);
+	tty_ldisc_flush(tty);
 	tty->closing = 0;
 	
 	pCh->pTTY = NULL;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/isicom.c linux-2.4.29-pre3/drivers/char/isicom.c
--- linux-2.4.28/drivers/char/isicom.c	2003-06-13 14:51:33.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/isicom.c	2004-12-22 16:05:32.294509816 +0000
@@ -502,11 +502,8 @@ static void isicom_bottomhalf(void * dat
 	
 	if (!tty)
 		return;
-	
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
-	wake_up_interruptible(&tty->write_wait);
+
+	tty_wakeup(tty);	
 } 		
  		
 /* main interrupt handler routine */ 		
@@ -1199,8 +1196,8 @@ static void isicom_close(struct tty_stru
 	isicom_shutdown_port(port);
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	
+	tty_ldisc_flush(tty);
 	tty->closing = 0;
 	port->tty = 0;
 	if (port->blocked_open) {
@@ -1670,10 +1667,7 @@ static void isicom_flush_buffer(struct t
 	port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
 	restore_flags(flags);
 	
-	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
+	tty_wakeup(tty);
 }
 
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/istallion.c linux-2.4.29-pre3/drivers/char/istallion.c
--- linux-2.4.28/drivers/char/istallion.c	2004-12-22 16:17:16.256491328 +0000
+++ linux-2.4.29-pre3/drivers/char/istallion.c	2004-12-22 16:07:02.748758680 +0000
@@ -3,7 +3,7 @@
 /*
  *	istallion.c  -- stallion intelligent multiport serial driver.
  *
- *	Copyright (C) 1996-1999  Stallion Technologies (support@stallion.oz.au).
+ *	Copyright (C) 1996-1999  Stallion Technologies
  *	Copyright (C) 1994-1996  Greg Ungerer.
  *
  *	This code is loosely based on the Linux serial driver, written by
@@ -1214,8 +1214,7 @@ static void stli_close(struct tty_struct
 	clear_bit(ST_TXBUSY, &portp->state);
 	clear_bit(ST_RXSTOP, &portp->state);
 	set_bit(TTY_IO_ERROR, &tty->flags);
-	if (tty->ldisc.flush_buffer)
-		(tty->ldisc.flush_buffer)(tty);
+	tty_ldisc_flush(tty);
 	set_bit(ST_DOFLUSHRX, &portp->state);
 	stli_flushbuffer(tty);
 
@@ -2477,10 +2476,7 @@ static void stli_flushbuffer(struct tty_
 	}
 	restore_flags(flags);
 
-	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
+	tty_wakeup(tty);
 }
 
 /*****************************************************************************/
@@ -2915,6 +2911,7 @@ static inline int stli_hostcmd(stlibrd_t
 	asynotify_t		nt;
 	unsigned long		oldsigs;
 	int			rc, donerx;
+	struct tty_ldisc	*ld;
 
 #if DEBUG
 	printk(KERN_DEBUG "stli_hostcmd(brdp=%x,channr=%d)\n",
@@ -3014,10 +3011,15 @@ static inline int stli_hostcmd(stlibrd_t
 			clear_bit(ST_TXBUSY, &portp->state);
 		if (nt.data & (DT_TXEMPTY | DT_TXLOW)) {
 			if (tty != (struct tty_struct *) NULL) {
-				if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-				    tty->ldisc.write_wakeup) {
-					(tty->ldisc.write_wakeup)(tty);
-					EBRDENABLE(brdp);
+				if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP))) {
+					ld = tty_ldisc_ref(tty);
+					if(ld) {
+						if(ld->write_wakeup) {
+							ld->write_wakeup(tty);
+							EBRDENABLE(brdp);
+						}
+						tty_ldisc_deref(ld);
+					}
 				}
 				wake_up_interruptible(&tty->write_wait);
 			}
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/ite_gpio.c linux-2.4.29-pre3/drivers/char/ite_gpio.c
--- linux-2.4.28/drivers/char/ite_gpio.c	2003-08-25 11:44:41.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/ite_gpio.c	2004-12-22 16:07:11.204473216 +0000
@@ -236,10 +236,6 @@ EXPORT_SYMBOL(ite_gpio_int_wait);
 
 static int ite_gpio_open(struct inode *inode, struct file *file)
 {
-	unsigned int minor = MINOR(inode->i_rdev); 
-	if (minor != GPIO_MINOR)
-		return -ENODEV;
-
 #ifdef MODULE
 	MOD_INC_USE_COUNT;
 #endif
@@ -250,7 +246,6 @@ static int ite_gpio_open(struct inode *i
 
 static int ite_gpio_release(struct inode *inode, struct file *file)
 {
-
 #ifdef MODULE
 	MOD_DEC_USE_COUNT;
 #endif
@@ -262,7 +257,6 @@ static int ite_gpio_release(struct inode
 static int ite_gpio_ioctl(struct inode *inode, struct file *file,
 	unsigned int cmd, unsigned long arg)
 {
-
 	static struct ite_gpio_ioctl_data ioctl_data;
 
 	if (copy_from_user(&ioctl_data, (struct ite_gpio_ioctl_data *)arg,
@@ -324,7 +318,8 @@ static int ite_gpio_ioctl(struct inode *
 	return 0;
 }
 
-static void ite_gpio_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs)
+static void ite_gpio_irq_handler(int this_irq, void *dev_id,
+	struct pt_regs *regs)
 {
 	int i,line;
 
@@ -369,23 +364,20 @@ DEB(printk("interrupt 0x%x %d\n",ITE_GPA
 	}
 }
 
-static struct file_operations ite_gpio_fops =
-{
+static struct file_operations ite_gpio_fops = {
 	owner:		THIS_MODULE,
 	ioctl:		ite_gpio_ioctl,
 	open:		ite_gpio_open,
 	release:	ite_gpio_release,
 };
 
-/* GPIO_MINOR in include/linux/miscdevice.h */
-static struct miscdevice ite_gpio_miscdev =
-{
-	GPIO_MINOR,
+static struct miscdevice ite_gpio_miscdev = {
+	MISC_DYNAMIC_MINOR,
 	"ite_gpio",
 	&ite_gpio_fops
 };
 
-int __init ite_gpio_init(void)
+static int __init ite_gpio_init(void)
 {
 	int i;
 
@@ -417,7 +409,7 @@ int __init ite_gpio_init(void)
 	return 0;
 }	
 
-void __exit ite_gpio_exit(void)
+static void __exit ite_gpio_exit(void)
 {
 	misc_deregister(&ite_gpio_miscdev);
 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/lcd.c linux-2.4.29-pre3/drivers/char/lcd.c
--- linux-2.4.28/drivers/char/lcd.c	2003-08-25 11:44:41.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/lcd.c	2004-12-22 16:06:08.906943880 +0000
@@ -556,9 +556,8 @@ static struct file_operations lcd_fops =
 	open:		lcd_open,
 };
 
-static struct miscdevice lcd_dev=
-{
-	LCD_MINOR,
+static struct miscdevice lcd_dev = {
+	MISC_DYNAMIC_MINOR,
 	"lcd",
 	&lcd_fops
 };
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/lp.c linux-2.4.29-pre3/drivers/char/lp.c
--- linux-2.4.28/drivers/char/lp.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/lp.c	2004-12-22 16:05:31.918566968 +0000
@@ -12,7 +12,7 @@
  * "lp=" command line parameters added by Grant Guenther, grant@torque.net
  * lp_read (Status readback) support added by Carsten Gross,
  *                                             carsten@sol.wohnheim.uni-ulm.de
- * Support for parport by Philip Blundell <Philip.Blundell@pobox.com>
+ * Support for parport by Philip Blundell <philb@gnu.org>
  * Parport sharing hacking by Andrea Arcangeli
  * Fixed kernel_(to/from)_user memory copy to check for errors
  * 				by Riccardo Facchetti <fizban@tin.it>
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/moxa.c linux-2.4.29-pre3/drivers/char/moxa.c
--- linux-2.4.28/drivers/char/moxa.c	2001-10-25 20:53:47.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/moxa.c	2004-12-22 16:07:40.537013992 +0000
@@ -677,8 +677,8 @@ static void moxa_close(struct tty_struct
 
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	tty_ldisc_flush(tty);
+
 	tty->closing = 0;
 	ch->event = 0;
 	ch->tty = 0;
@@ -754,10 +754,7 @@ static void moxa_flush_buffer(struct tty
 	if (ch == NULL)
 		return;
 	MoxaPortFlushData(ch->port, 1);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup) (tty);
-	wake_up_interruptible(&tty->write_wait);
+	tty_wakeup(tty);
 }
 
 static int moxa_chars_in_buffer(struct tty_struct *tty)
@@ -1011,10 +1008,7 @@ static void moxa_poll(unsigned long igno
 				if (MoxaPortTxQueue(ch->port) <= WAKEUP_CHARS) {
 					if (!tp->stopped) {
 						ch->statusflags &= ~LOWWAIT;
-						if ((tp->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-						  tp->ldisc.write_wakeup)
-							(tp->ldisc.write_wakeup) (tp);
-						wake_up_interruptible(&tp->write_wait);
+						tty_wakeup(tp);
 					}
 				}
 			}
@@ -1203,10 +1197,7 @@ static void check_xmit_empty(unsigned lo
 	if (ch->tty && (ch->statusflags & EMPTYWAIT)) {
 		if (MoxaPortTxQueue(ch->port) == 0) {
 			ch->statusflags &= ~EMPTYWAIT;
-			if ((ch->tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-			    ch->tty->ldisc.write_wakeup)
-				(ch->tty->ldisc.write_wakeup) (ch->tty);
-			wake_up_interruptible(&ch->tty->write_wait);
+			tty_wakeup(ch->tty);
 			return;
 		}
 		moxaEmptyTimer[ch->port].expires = jiffies + HZ;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/mux.c linux-2.4.29-pre3/drivers/char/mux.c
--- linux-2.4.28/drivers/char/mux.c	2003-06-13 14:51:33.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/mux.c	2004-12-22 16:05:31.043699968 +0000
@@ -429,8 +429,7 @@ mux_close(struct tty_struct *tty, struct
 
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	tty_ldisc_flush(tty);
 	tty->closing = 0;
 	info->event = 0;
 	info->tty = 0;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/mxser.c linux-2.4.29-pre3/drivers/char/mxser.c
--- linux-2.4.28/drivers/char/mxser.c	2004-12-22 16:17:16.270489200 +0000
+++ linux-2.4.29-pre3/drivers/char/mxser.c	2004-12-22 16:07:11.170478384 +0000
@@ -725,10 +725,7 @@ static void mxser_do_softint(void *priva
 	tty = info->tty;
 	if (tty) {
 		if (test_and_clear_bit(MXSER_EVENT_TXLOW, &info->event)) {
-			if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-			    tty->ldisc.write_wakeup)
-				(tty->ldisc.write_wakeup) (tty);
-			wake_up_interruptible(&tty->write_wait);
+			tty_wakeup(tty);
 		}
 		if (test_and_clear_bit(MXSER_EVENT_HANGUP, &info->event)) {
 			tty_hangup(tty);	/* FIXME: module removal race here - AKPM */
@@ -890,8 +887,8 @@ static void mxser_close(struct tty_struc
 	mxser_shutdown(info);
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	tty_ldisc_flush(tty);
+
 	tty->closing = 0;
 	info->event = 0;
 	info->tty = 0;
@@ -1050,10 +1047,7 @@ static void mxser_flush_buffer(struct tt
 	cli();
 	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
 	restore_flags(flags);
-	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup) (tty);
+	tty_wakeup(tty);
 }
 
 static int mxser_ioctl(struct tty_struct *tty, struct file *file,
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/n_hdlc.c linux-2.4.29-pre3/drivers/char/n_hdlc.c
--- linux-2.4.28/drivers/char/n_hdlc.c	2003-11-28 18:26:20.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/n_hdlc.c	2004-12-22 16:06:05.939395016 +0000
@@ -351,9 +351,8 @@ static int n_hdlc_tty_open (struct tty_s
 #endif
 	
 	/* Flush any pending characters in the driver and discipline. */
-	
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer (tty);
+
+	tty_ldisc_flush(tty);	
 
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer (tty);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/n_r3964.c linux-2.4.29-pre3/drivers/char/n_r3964.c
--- linux-2.4.28/drivers/char/n_r3964.c	2003-06-13 14:51:33.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/n_r3964.c	2004-12-22 16:07:41.595853024 +0000
@@ -158,7 +158,8 @@ static struct tty_ldisc tty_ldisc_N_R396
         r3964_write,           /* write */
         r3964_ioctl,           /* ioctl */
         r3964_set_termios,     /* set_termios */
-        r3964_poll,            /* poll */            
+        r3964_poll,            /* poll */
+        NULL,                  /* hangup */
         r3964_receive_buf,     /* receive_buf */
         r3964_receive_room,    /* receive_room */
         0                      /* write_wakeup */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/n_tty.c linux-2.4.29-pre3/drivers/char/n_tty.c
--- linux-2.4.28/drivers/char/n_tty.c	2003-08-25 11:44:41.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/n_tty.c	2004-12-22 16:05:32.000554504 +0000
@@ -112,11 +112,18 @@ static inline void put_tty_queue(unsigne
 	spin_unlock_irqrestore(&tty->read_lock, flags);
 }
 
-/* 
- * Check whether to call the driver.unthrottle function.
- * We test the TTY_THROTTLED bit first so that it always
- * indicates the current state.
+/**
+ *	check_unthrottle	-	allow new receive data
+ *	@tty; tty device
+ *
+ *	Check whether to call the driver.unthrottle function.
+ *	We test the TTY_THROTTLED bit first so that it always
+ *	indicates the current state. The decision about whether
+ *	it is worth allowing more input has been taken by the caller.
+ *	Can sleep, may be called under the atomic_read semaphore but
+ *	this is not guaranteed.
  */
+ 
 static void check_unthrottle(struct tty_struct * tty)
 {
 	if (tty->count &&
@@ -125,10 +132,13 @@ static void check_unthrottle(struct tty_
 		tty->driver.unthrottle(tty);
 }
 
-/*
- * Reset the read buffer counters, clear the flags, 
- * and make sure the driver is unthrottled. Called
- * from n_tty_open() and n_tty_flush_buffer().
+/**
+ *	reset_buffer_flags	-	reset buffer state
+ *	@tty: terminal to reset
+ *
+ *	Reset the read buffer counters, clear the flags, 
+ *	and make sure the driver is unthrottled. Called
+ *	from n_tty_open() and n_tty_flush_buffer().
  */
 static void reset_buffer_flags(struct tty_struct *tty)
 {
@@ -142,9 +152,19 @@ static void reset_buffer_flags(struct tt
 	check_unthrottle(tty);
 }
 
-/*
- * Flush the input buffer
+/**
+ *	n_tty_flush_buffer	-	clean input queue
+ *	@tty:	terminal device
+ *
+ *	Flush the input buffer. Called when the line discipline is
+ *	being closed, when the tty layer wants the buffer flushed (eg
+ *	at hangup) or when the N_TTY line discipline internally has to
+ *	clean the pending queue (for example some signals).
+ *
+ *	FIXME: tty->ctrl_status is not spinlocked and relies on
+ *	lock_kernel() still.
  */
+ 
 void n_tty_flush_buffer(struct tty_struct * tty)
 {
 	/* clear everything and unthrottle the driver */
@@ -159,9 +179,14 @@ void n_tty_flush_buffer(struct tty_struc
 	}
 }
 
-/*
- * Return number of characters buffered to be delivered to user
+/**
+ *	n_tty_chars_in_buffer	-	report available bytes
+ *	@tty: tty device
+ *
+ *	Report the number of characters buffered to be delivered to user
+ *	at this instant in time. 
  */
+ 
 ssize_t n_tty_chars_in_buffer(struct tty_struct *tty)
 {
 	unsigned long flags;
@@ -242,10 +267,20 @@ static int opost(unsigned char c, struct
 	return 0;
 }
 
-/*
- * opost_block --- to speed up block console writes, among other
- * things.
+/**
+ *	opost_block		-	block postprocess
+ *	@tty: terminal device
+ *	@inbuf: user buffer
+ *	@nr: number of bytes
+ *
+ *	This path is used to speed up block console writes, among other
+ *	things when processing blocks of output data. It handles only
+ *	the simple cases normally found and helps to generate blocks of
+ *	symbols for the console driver and thus improve performance.
+ *
+ *	Called from write_chan under the tty layer write lock.
  */
+ 
 static ssize_t opost_block(struct tty_struct * tty,
 		       const unsigned char * inbuf, unsigned int nr)
 {
@@ -334,6 +369,16 @@ static inline void finish_erasing(struct
 	}
 }
 
+/**
+ *	eraser		-	handle erase function
+ *	@c: character input
+ *	@tty: terminal device
+ *
+ *	Perform erase and neccessary output when an erase character is
+ *	present in the stream from the driver layer. Handles the complexities
+ *	of UTF-8 multibyte symbols.
+ */
+ 
 static void eraser(unsigned char c, struct tty_struct *tty)
 {
 	enum { ERASE, WERASE, KILL } kill_type;
@@ -450,6 +495,18 @@ static void eraser(unsigned char c, stru
 		finish_erasing(tty);
 }
 
+/**
+ *	isig		-	handle the ISIG optio
+ *	@sig: signal
+ *	@tty: terminal
+ *	@flush: force flush
+ *
+ *	Called when a signal is being sent due to terminal input. This
+ *	may caus terminal flushing to take place according to the termios
+ *	settings and character used. Called from the driver receive_buf
+ *	path so serialized.
+ */
+ 
 static inline void isig(int sig, struct tty_struct *tty, int flush)
 {
 	if (tty->pgrp > 0)
@@ -461,6 +518,16 @@ static inline void isig(int sig, struct 
 	}
 }
 
+/**
+ *	n_tty_receive_break	-	handle break
+ *	@tty: terminal
+ *
+ *	An RS232 break event has been hit in the incoming bitstream. This
+ *	can cause a variety of events depending upon the termios settings.
+ *
+ *	Called from the receive_buf path so single threaded.
+ */
+ 
 static inline void n_tty_receive_break(struct tty_struct *tty)
 {
 	if (I_IGNBRK(tty))
@@ -477,19 +544,40 @@ static inline void n_tty_receive_break(s
 	wake_up_interruptible(&tty->read_wait);
 }
 
+/**
+ *	n_tty_receive_overrun	-	handle overrun reporting
+ *	@tty: terminal
+ *
+ *	Data arrived faster than we could process it. While the tty
+ *	driver has flagged this the bits that were missed are gone
+ *	forever.
+ *
+ *	Called from the receive_buf path so single threaded. Does not
+ *	need locking as num_overrun and overrun_time are function
+ *	private.
+ */
+ 
 static inline void n_tty_receive_overrun(struct tty_struct *tty)
 {
 	char buf[64];
 
 	tty->num_overrun++;
 	if (time_before(tty->overrun_time, jiffies - HZ)) {
-		printk("%s: %d input overrun(s)\n", tty_name(tty, buf),
+		printk(KERN_WARNING "%s: %d input overrun(s)\n", tty_name(tty, buf),
 		       tty->num_overrun);
 		tty->overrun_time = jiffies;
 		tty->num_overrun = 0;
 	}
 }
 
+/**
+ *	n_tty_receive_parity_error	-	error notifier
+ *	@tty: terminal device
+ *	@c: character
+ *
+ *	Process a parity error and queue the right data to indicate
+ *	the error case if neccessary. Locking as per n_tty_receive_buf.
+ */
 static inline void n_tty_receive_parity_error(struct tty_struct *tty,
 					      unsigned char c)
 {
@@ -507,6 +595,16 @@ static inline void n_tty_receive_parity_
 	wake_up_interruptible(&tty->read_wait);
 }
 
+/**
+ *	n_tty_receive_char	-	perform processing
+ *	@tty: terminal device
+ *	@c: character
+ *
+ *	Process an individual character of input received from the driver.
+ *	This is serialized with respect to itself by the rules for the 
+ *	driver above.
+ */
+
 static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
 {
 	unsigned long flags;
@@ -698,6 +796,16 @@ send_signal:
 	put_tty_queue(c, tty);
 }	
 
+/**
+ *	n_tty_receive_room	-	receive space
+ *	@tty: terminal
+ *
+ *	Called by the driver to find out how much data it is
+ *	permitted to feed to the line discipline without any being lost
+ *	and thus to manage flow control. Not serialized. Answers for the
+ *	"instant".
+ */
+ 
 static int n_tty_receive_room(struct tty_struct *tty)
 {
 	int	left = N_TTY_BUF_SIZE - tty->read_cnt - 1;
@@ -716,10 +824,13 @@ static int n_tty_receive_room(struct tty
 	return 0;
 }
 
-/*
- * Required for the ptys, serial driver etc. since processes
- * that attach themselves to the master and rely on ASYNC
- * IO must be woken up
+/**
+ *	n_tty_write_wakeup	-	asynchronous I/O notifier
+ *	@tty: tty device
+ *
+ *	Required for the ptys, serial driver etc. since processes
+ *	that attach themselves to the master and rely on ASYNC
+ *	IO must be woken up
  */
 
 static void n_tty_write_wakeup(struct tty_struct *tty)
@@ -732,6 +843,19 @@ static void n_tty_write_wakeup(struct tt
 	return;
 }
 
+/**
+ *	n_tty_receive_buf	-	data receive
+ *	@tty: terminal device
+ *	@cp: buffer
+ *	@fp: flag buffer
+ *	@count: characters
+ *
+ *	Called by the terminal driver when a block of characters has
+ *	been received. This function must be called from soft contexts
+ *	not from interrupt context. The driver is responsible for making
+ *	calls one at a time and in order (or using queue_ldisc)
+ */
+ 
 static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
 			      char *fp, int count)
 {
@@ -813,6 +937,18 @@ int is_ignored(int sig)
 	        current->sig->action[sig-1].sa.sa_handler == SIG_IGN);
 }
 
+/**
+ *	n_tty_set_termios	-	termios data changed
+ *	@tty: terminal
+ *	@old: previous data
+ *
+ *	Called by the tty layer when the user changes termios flags so
+ *	that the line discipline can plan ahead. This function cannot sleep
+ *	and is protected from re-entry by the tty layer. The user is 
+ *	guaranteed that this function will not be re-entered or in progress
+ *	when the ldisc is closed.
+ */
+ 
 static void n_tty_set_termios(struct tty_struct *tty, struct termios * old)
 {
 	if (!tty)
@@ -828,7 +964,6 @@ static void n_tty_set_termios(struct tty
 	    I_ICRNL(tty) || I_INLCR(tty) || L_ICANON(tty) ||
 	    I_IXON(tty) || L_ISIG(tty) || L_ECHO(tty) ||
 	    I_PARMRK(tty)) {
-		cli();
 		memset(tty->process_char_map, 0, 256/8);
 
 		if (I_IGNCR(tty) || I_ICRNL(tty))
@@ -864,7 +999,6 @@ static void n_tty_set_termios(struct tty
 			set_bit(SUSP_CHAR(tty), &tty->process_char_map);
 		}
 		clear_bit(__DISABLED_CHAR, &tty->process_char_map);
-		sti();
 		tty->raw = 0;
 		tty->real_raw = 0;
 	} else {
@@ -878,6 +1012,16 @@ static void n_tty_set_termios(struct tty
 	}
 }
 
+/**
+ *	n_tty_close		-	close the ldisc for this tty
+ *	@tty: device
+ *
+ *	Called from the terminal layer when this line discipline is 
+ *	being shut down, either because of a close or becsuse of a 
+ *	discipline change. The function will not be called while other
+ *	ldisc methods are in progress.
+ */
+ 
 static void n_tty_close(struct tty_struct *tty)
 {
 	n_tty_flush_buffer(tty);
@@ -887,11 +1031,22 @@ static void n_tty_close(struct tty_struc
 	}
 }
 
+/**
+ *	n_tty_open		-	open an ldisc
+ *	@tty: terminal to open
+ *
+ *	Called when this line discipline is being attached to the 
+ *	terminal device. Can sleep. Called serialized so that no
+ *	other events will occur in parallel. No further open will occur
+ *	until a close.
+ */
+
 static int n_tty_open(struct tty_struct *tty)
 {
 	if (!tty)
 		return -EINVAL;
 
+	/* This one is ugly. Currently a malloc failure here can panic */
 	if (!tty->read_buf) {
 		tty->read_buf = alloc_buf();
 		if (!tty->read_buf)
@@ -917,14 +1072,23 @@ static inline int input_available_p(stru
 	return 0;
 }
 
-/*
- * Helper function to speed up read_chan.  It is only called when
- * ICANON is off; it copies characters straight from the tty queue to
- * user space directly.  It can be profitably called twice; once to
- * drain the space from the tail pointer to the (physical) end of the
- * buffer, and once to drain the space from the (physical) beginning of
- * the buffer to head pointer.
+/**
+ * 	copy_from_read_buf	-	copy read data directly
+ *	@tty: terminal device
+ *	@b: user data
+ *	@nr: size of data
+ *
+ *	Helper function to speed up read_chan.  It is only called when
+ *	ICANON is off; it copies characters straight from the tty queue to
+ *	user space directly.  It can be profitably called twice; once to
+ *	drain the space from the tail pointer to the (physical) end of the
+ *	buffer, and once to drain the space from the (physical) beginning of
+ *	the buffer to head pointer.
+ *
+ *	Called under the tty->atomic_read sem and with TTY_DONT_FLIP set
+ *
  */
+ 
 static inline int copy_from_read_buf(struct tty_struct *tty,
 				      unsigned char **b,
 				      size_t *nr)
@@ -952,25 +1116,18 @@ static inline int copy_from_read_buf(str
 	return retval;
 }
 
-static ssize_t read_chan(struct tty_struct *tty, struct file *file,
-			 unsigned char *buf, size_t nr)
-{
-	unsigned char *b = buf;
-	DECLARE_WAITQUEUE(wait, current);
-	int c;
-	int minimum, time;
-	ssize_t retval = 0;
-	ssize_t size;
-	long timeout;
-	unsigned long flags;
-
-do_it_again:
-
-	if (!tty->read_buf) {
-		printk("n_tty_read_chan: called with read_buf == NULL?!?\n");
-		return -EIO;
-	}
+/**
+ *     job_control             -       check job control
+ *     @tty: tty
+ *     @file: file handle
+ *
+ *     Perform job control management checks on this file/tty descriptor
+ *     and if appropriate send any needed signals and return a negative
+ *     error code if action should be taken.
+ */
 
+static int job_control(struct tty_struct *tty, struct file *file)
+{
 	/* Job control check -- must be done at start and after
 	   every sleep (POSIX.1 7.1.1.4). */
 	/* NOTE: not yet done after every sleep pending a thorough
@@ -989,7 +1146,48 @@ do_it_again:
 			return -ERESTARTSYS;
 		}
 	}
+	return 0;
+}
+ 
 
+/**
+ *	read_chan		-	read function for tty
+ *	@tty: tty device
+ *	@file: file object
+ *	@buf: userspace buffer pointer
+ *	@nr: size of I/O
+ *
+ *	Perform reads for the line discipline. We are guaranteed that the
+ *	line discipline will not be closed under us but we may get multiple
+ *	parallel readers and must handle this ourselves. We may also get
+ *	a hangup. Always called in user context, may sleep.
+ *
+ *	This code must be sure never to sleep through a hangup.
+ */
+ 
+static ssize_t read_chan(struct tty_struct *tty, struct file *file,
+			 unsigned char __user *buf, size_t nr)
+{
+	unsigned char __user *b = buf;
+	DECLARE_WAITQUEUE(wait, current);
+	int c;
+	int minimum, time;
+	ssize_t retval = 0;
+	ssize_t size;
+	long timeout;
+	unsigned long flags;
+
+do_it_again:
+
+	if (!tty->read_buf) {
+		printk("n_tty_read_chan: called with read_buf == NULL?!?\n");
+		return -EIO;
+	}
+
+	c = job_control(tty, file);
+	if(c < 0)
+		return c;
+	
 	minimum = time = 0;
 	timeout = MAX_SCHEDULE_TIMEOUT;
 	if (!tty->icanon) {
@@ -1011,6 +1209,9 @@ do_it_again:
 		}
 	}
 
+	/*
+	 *	Internal serialization of reads.
+	 */
 	if (file->f_flags & O_NONBLOCK) {
 		if (down_trylock(&tty->atomic_read))
 			return -EAGAIN;
@@ -1146,6 +1347,21 @@ do_it_again:
 	return retval;
 }
 
+/**
+ *	write_chan		-	write function for tty
+ *	@tty: tty device
+ *	@file: file object
+ *	@buf: userspace buffer pointer
+ *	@nr: size of I/O
+ *
+ *	Write function of the terminal device. This is serialized with
+ *	respect to other write callers but not to termios changes, reads
+ *	and other such events. We must be careful with N_TTY as the receive
+ *	code will echo characters, thus calling driver write methods.
+ *
+ *	This code must be sure never to sleep through a hangup.
+ */
+ 
 static ssize_t write_chan(struct tty_struct * tty, struct file * file,
 			  const unsigned char * buf, size_t nr)
 {
@@ -1217,7 +1433,25 @@ break_out:
 	return (b - buf) ? b - buf : retval;
 }
 
-/* Called without the kernel lock held - fine */
+/**
+ *	normal_poll		-	poll method for N_TTY
+ *	@tty: terminal device
+ *	@file: file accessing it
+ *	@wait: poll table
+ *
+ *	Called when the line discipline is asked to poll() for data or
+ *	for special events. This code is not serialized with respect to
+ *	other events save open/close.
+ *
+ *	This code must be sure never to sleep through a hangup.
+ *	Called without the kernel lock held - fine
+ *
+ *	FIXME: if someone changes the VMIN or discipline settings for the
+ *	terminal while another process is in poll() the poll does not
+ *	recompute the new limits. Possibly set_termios should issue
+ *	a read wakeup to fix this bug.
+ */
+ 
 static unsigned int normal_poll(struct tty_struct * tty, struct file * file, poll_table *wait)
 {
 	unsigned int mask = 0;
@@ -1258,6 +1492,7 @@ struct tty_ldisc tty_ldisc_N_TTY = {
 	n_tty_ioctl,		/* ioctl */
 	n_tty_set_termios,	/* set_termios */
 	normal_poll,		/* poll */
+	NULL,			/* hangup */
 	n_tty_receive_buf,	/* receive_buf */
 	n_tty_receive_room,	/* receive_room */
 	n_tty_write_wakeup	/* write_wakeup */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/pcmcia/synclink_cs.c linux-2.4.29-pre3/drivers/char/pcmcia/synclink_cs.c
--- linux-2.4.28/drivers/char/pcmcia/synclink_cs.c	2003-11-28 18:26:20.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/pcmcia/synclink_cs.c	2004-12-22 16:06:45.398396336 +0000
@@ -553,6 +553,29 @@ static void cs_error(client_handle_t han
 static void* mgslpc_get_text_ptr(void);
 static void* mgslpc_get_text_ptr() {return mgslpc_get_text_ptr;}
 
+/**
+ * line discipline callback wrappers
+ *
+ * The wrappers maintain line discipline references
+ * while calling into the line discipline.
+ *
+ * ldisc_receive_buf  - pass receive data to line discipline
+ */
+
+static void ldisc_receive_buf(struct tty_struct *tty,
+			      const __u8 *data, char *flags, int count)
+{
+	struct tty_ldisc *ld;
+	if (!tty)
+		return;
+	ld = tty_ldisc_ref(tty);
+	if (ld) {
+		if (ld->receive_buf)
+			ld->receive_buf(tty, data, flags, count);
+		tty_ldisc_deref(ld);
+	}
+}
+
 static dev_link_t *mgslpc_attach(void)
 {
     MGSLPC_INFO *info;
@@ -1027,13 +1050,7 @@ void bh_transmit(MGSLPC_INFO *info)
 		printk("bh_transmit() entry on %s\n", info->device_name);
 
 	if (tty) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup) {
-			if ( debug_level >= DEBUG_LEVEL_BH )
-				printk( "%s(%d):calling ldisc.write_wakeup on %s\n",
-					__FILE__,__LINE__,info->device_name);
-			(tty->ldisc.write_wakeup)(tty);
-		}
+		tty_wakeup(tty);
 		wake_up_interruptible(&tty->write_wait);
 	}
 }
@@ -1917,11 +1934,9 @@ static void mgslpc_flush_buffer(struct t
 	info->tx_count = info->tx_put = info->tx_get = 0;
 	del_timer(&info->tx_timer);	
 	spin_unlock_irqrestore(&info->lock,flags);
-	
+
 	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
+	tty_wakeup(tty);
 }
 
 /* Send a high-priority XON/XOFF character
@@ -2685,9 +2700,8 @@ static void mgslpc_close(struct tty_stru
 
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-		
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	
+	tty_ldisc_flush(tty);
 		
 	shutdown(info);
 	
@@ -4199,11 +4213,7 @@ int rx_get_frame(MGSLPC_INFO *info)
 			} 
 			else
 #endif
-			{
-				/* Call the line discipline receive callback directly. */
-				if (tty && tty->ldisc.receive_buf)
-					tty->ldisc.receive_buf(tty, buf->data, info->flag_buf, framesize);
-			}
+				ldisc_receive_buf(tty, buf->data, info->flag_buf, framesize);
 		}
 	}
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/pcxx.c linux-2.4.29-pre3/drivers/char/pcxx.c
--- linux-2.4.28/drivers/char/pcxx.c	2002-11-28 23:53:12.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/pcxx.c	2004-12-22 16:07:00.954031520 +0000
@@ -619,28 +619,11 @@ static void pcxe_close(struct tty_struct
 	
 		if(tty->driver.flush_buffer)
 			tty->driver.flush_buffer(tty);
-		if(tty->ldisc.flush_buffer)
-			tty->ldisc.flush_buffer(tty);
+		tty_ldisc_flush(tty);
 		shutdown(info);
 		tty->closing = 0;
 		info->event = 0;
 		info->tty = NULL;
-#ifndef MODULE
-/* ldiscs[] is not available in a MODULE
-** worth noting that while I'm not sure what this hunk of code is supposed
-** to do, it is not present in the serial.c driver.  Hmmm.  If you know,
-** please send me a note.  brian@ilinx.com
-** Don't know either what this is supposed to do christoph@lameter.com.
-*/
-		if(tty->ldisc.num != ldiscs[N_TTY].num) {
-			if(tty->ldisc.close)
-				(tty->ldisc.close)(tty);
-			tty->ldisc = ldiscs[N_TTY];
-			tty->termios->c_line = N_TTY;
-			if(tty->ldisc.open)
-				(tty->ldisc.open)(tty);
-		}
-#endif
 		if(info->blocked_open) {
 			if(info->close_delay) {
 				current->state = TASK_INTERRUPTIBLE;
@@ -883,9 +866,7 @@ static void pcxe_flush_buffer(struct tty
 	memoff(ch);
 	restore_flags(flags);
 
-	wake_up_interruptible(&tty->write_wait);
-	if((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
+	tty_wakeup(tty);
 }
 
 static void pcxe_flush_chars(struct tty_struct *tty)
@@ -1793,10 +1774,7 @@ static void doevent(int crd)
 			if (event & LOWTX_IND) {
 				if (ch->statusflags & LOWWAIT) {
 					ch->statusflags &= ~LOWWAIT;
-					if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-						tty->ldisc.write_wakeup)
-						(tty->ldisc.write_wakeup)(tty);
-					wake_up_interruptible(&tty->write_wait);
+					tty_wakeup(tty);
 				}
 			}
 
@@ -1804,10 +1782,7 @@ static void doevent(int crd)
 				ch->statusflags &= ~TXBUSY;
 				if (ch->statusflags & EMPTYWAIT) {
 					ch->statusflags &= ~EMPTYWAIT;
-					if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-						tty->ldisc.write_wakeup)
-						(tty->ldisc.write_wakeup)(tty);
-					wake_up_interruptible(&tty->write_wait);
+					tty_wakeup(tty);
 				}
 			}
 		}
@@ -2254,8 +2229,7 @@ static int pcxe_ioctl(struct tty_struct 
 				tty_wait_until_sent(tty, 0);
 			}
 			else {
-				if(tty->ldisc.flush_buffer)
-					tty->ldisc.flush_buffer(tty);
+				tty_ldisc_flush(tty);
 			}
 
 			/* Fall Thru */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/pdc_console.c linux-2.4.29-pre3/drivers/char/pdc_console.c
--- linux-2.4.28/drivers/char/pdc_console.c	2003-06-13 14:51:33.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/pdc_console.c	2004-12-22 16:06:36.230790024 +0000
@@ -463,8 +463,7 @@ pdc_close(struct tty_struct *tty, struct
 
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	tty_ldisc_flush(tty);
 	tty->closing = 0;
 	info->event = 0;
 	info->tty = 0;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/pty.c linux-2.4.29-pre3/drivers/char/pty.c
--- linux-2.4.28/drivers/char/pty.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/pty.c	2004-12-22 16:06:18.826435888 +0000
@@ -85,9 +85,9 @@ static void pty_close(struct tty_struct 
 	if (!tty->link)
 		return;
 	tty->link->packet = 0;
+	set_bit(TTY_OTHER_CLOSED, &tty->link->flags);
 	wake_up_interruptible(&tty->link->read_wait);
 	wake_up_interruptible(&tty->link->write_wait);
-	set_bit(TTY_OTHER_CLOSED, &tty->link->flags);
 	if (tty->driver.subtype == PTY_TYPE_MASTER) {
 		set_bit(TTY_OTHER_CLOSED, &tty->flags);
 #ifdef CONFIG_UNIX98_PTYS
@@ -121,10 +121,7 @@ static void pty_unthrottle(struct tty_st
 	if (!o_tty)
 		return;
 
-	if ((o_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    o_tty->ldisc.write_wakeup)
-		(o_tty->ldisc.write_wakeup)(o_tty);
-	wake_up_interruptible(&o_tty->write_wait);
+	tty_wakeup(o_tty);
 	set_bit(TTY_THROTTLED, &tty->flags);
 }
 
@@ -137,6 +134,10 @@ static void pty_unthrottle(struct tty_st
  *   (2) avoid redundant copying for cases where count >> receive_room
  * N.B. Calls from user space may now return an error code instead of
  * a count.
+ *
+ * FIXME: Our pty_write method is called with our ldisc lock held but
+ * not our partners. We can't just take the other one blindly without
+ * risking deadlocks.  There is also the small matter of TTY_DONT_FLIP
  */
 static int pty_write(struct tty_struct * tty, int from_user,
 		       const unsigned char *buf, int count)
@@ -299,9 +300,8 @@ static void pty_flush_buffer(struct tty_
 	
 	if (!to)
 		return;
-	
-	if (to->ldisc.flush_buffer)
-		to->ldisc.flush_buffer(to);
+
+	tty_ldisc_flush(to);	
 	
 	if (to->packet) {
 		tty->ctrl_status |= TIOCPKT_FLUSHWRITE;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/rio/riointr.c linux-2.4.29-pre3/drivers/char/rio/riointr.c
--- linux-2.4.28/drivers/char/rio/riointr.c	2001-09-10 16:04:53.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/rio/riointr.c	2004-12-22 16:05:30.695752864 +0000
@@ -248,12 +248,9 @@ char *		en;
     rio_dprintk (RIO_DEBUG_INTR, "Waking up.... ldisc:%d (%d/%d)....",
 		 (int)(PortP->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)),
 		 PortP->gs.wakeup_chars, PortP->gs.xmit_cnt); 
-    if ((PortP->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	PortP->gs.tty->ldisc.write_wakeup)
-      (PortP->gs.tty->ldisc.write_wakeup)(PortP->gs.tty);
+    tty_wakeup(PortP->gs.tty);
     rio_dprintk (RIO_DEBUG_INTR, "(%d/%d)\n",
 		PortP->gs.wakeup_chars, PortP->gs.xmit_cnt); 
-    wake_up_interruptible(&PortP->gs.tty->write_wait);
   }
 
 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/riscom8.c linux-2.4.29-pre3/drivers/char/riscom8.c
--- linux-2.4.28/drivers/char/riscom8.c	2001-09-13 22:21:32.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/riscom8.c	2004-12-22 16:06:38.575433584 +0000
@@ -1200,8 +1200,7 @@ static void rc_close(struct tty_struct *
 	rc_shutdown_port(bp, port);
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	tty_ldisc_flush(tty);
 	tty->closing = 0;
 	port->event = 0;
 	port->tty = 0;
@@ -1375,9 +1374,7 @@ static void rc_flush_buffer(struct tty_s
 	restore_flags(flags);
 	
 	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
+	tty_wakeup(tty);
 }
 
 static int rc_get_modem_info(struct riscom_port * port, unsigned int *value)
@@ -1734,10 +1731,7 @@ static void do_softint(void *private_)
 		return;
 
 	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup)(tty);
-		wake_up_interruptible(&tty->write_wait);
+		tty_wakeup(tty);
 	}
 }
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/rocket.c linux-2.4.29-pre3/drivers/char/rocket.c
--- linux-2.4.28/drivers/char/rocket.c	2003-11-28 18:26:20.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/rocket.c	2004-12-22 16:07:11.978355568 +0000
@@ -241,9 +241,12 @@ static _INLINE_ void rp_do_receive(struc
 				   CHANNEL_t *cp, unsigned int ChanStatus)
 {
 	unsigned int CharNStat;
-	int ToRecv, wRecv, space, count;
+	int ToRecv, wRecv, space = 0, count;
 	unsigned char	*cbuf;
 	char		*fbuf;
+	struct tty_ldisc *ld;
+
+	ld = tty_ldisc_ref(tty);
 	
 	ToRecv= sGetRxCnt(cp);
 	space = 2*TTY_FLIPBUF_SIZE;
@@ -348,8 +351,8 @@ static _INLINE_ void rp_do_receive(struc
 		fbuf += ToRecv;
 		count += ToRecv;
 	}
-	tty->ldisc.receive_buf(tty, tty->flip.char_buf,
-			       tty->flip.flag_buf, count);
+	ld->receive_buf(tty, tty->flip.char_buf, tty->flip.flag_buf, count);
+	tty_ldisc_deref(ld);
 }
 
 /*
@@ -400,10 +403,7 @@ static _INLINE_ void rp_do_transmit(stru
 	if (info->xmit_cnt == 0)
 		xmit_flags[info->line >> 5] &= ~(1 << (info->line & 0x1f));
 	if (info->xmit_cnt < WAKEUP_CHARS) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup)(tty);
-		wake_up_interruptible(&tty->write_wait);
+		tty_wakeup(tty);
 	}
 #ifdef ROCKET_DEBUG_INTR
 	printk("(%d,%d,%d,%d)...", info->xmit_cnt, info->xmit_head,
@@ -1128,8 +1128,7 @@ static void rp_close(struct tty_struct *
 	}
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	tty_ldisc_flush(tty);
 
 	xmit_flags[info->line >> 5] &= ~(1 << (info->line & 0x1f));
 	if (info->blocked_open) {
@@ -1806,10 +1805,7 @@ end_intr:
 	restore_flags(flags);
 end:
 	if (info->xmit_cnt < WAKEUP_CHARS) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup)(tty);
-		wake_up_interruptible(&tty->write_wait);
+		tty_wakeup(tty);
 	}
 	return retval;
 }
@@ -1868,9 +1864,7 @@ static void rp_flush_buffer(struct tty_s
 	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
 	sti();
 	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
+	tty_wakeup(tty);
 	
 	cp = &info->channel;
 	
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/selection.c linux-2.4.29-pre3/drivers/char/selection.c
--- linux-2.4.28/drivers/char/selection.c	2001-09-07 16:28:38.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/selection.c	2004-12-22 16:07:42.568705128 +0000
@@ -290,9 +290,11 @@ int paste_selection(struct tty_struct *t
 {
 	struct vt_struct *vt = (struct vt_struct *) tty->driver_data;
 	int	pasted = 0, count;
+	struct  tty_ldisc *ld;
 	DECLARE_WAITQUEUE(wait, current);
 
 	poke_blanked_console();
+	ld = tty_ldisc_ref_wait(tty);
 	add_wait_queue(&vt->paste_wait, &wait);
 	while (sel_buffer && sel_buffer_lth > pasted) {
 		set_current_state(TASK_INTERRUPTIBLE);
@@ -301,12 +303,14 @@ int paste_selection(struct tty_struct *t
 			continue;
 		}
 		count = sel_buffer_lth - pasted;
-		count = MIN(count, tty->ldisc.receive_room(tty));
-		tty->ldisc.receive_buf(tty, sel_buffer + pasted, 0, count);
+		count = MIN(count, ld->receive_room(tty));
+		ld->receive_buf(tty, sel_buffer + pasted, 0, count);
 		pasted += count;
 	}
 	remove_wait_queue(&vt->paste_wait, &wait);
 	current->state = TASK_RUNNING;
+
+	tty_ldisc_deref(ld);
 	return 0;
 }
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/ser_a2232.c linux-2.4.29-pre3/drivers/char/ser_a2232.c
--- linux-2.4.28/drivers/char/ser_a2232.c	2003-11-28 18:26:20.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/ser_a2232.c	2004-12-22 16:06:05.947393800 +0000
@@ -633,10 +633,7 @@ int ch, err, n, p;
 					
 				/* WakeUp if output buffer runs low */
 				if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.tty) {
-					if ((port->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && port->gs.tty->ldisc.write_wakeup){
-						(port->gs.tty->ldisc.write_wakeup)(port->gs.tty);
-					}
-					wake_up_interruptible(&port->gs.tty->write_wait);
+					tty_wakeup(port->gs.tty);
 				}
 			} // if the port is used
 		} // for every port on the board
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/serial.c linux-2.4.29-pre3/drivers/char/serial.c
--- linux-2.4.28/drivers/char/serial.c	2004-12-22 16:17:16.298484944 +0000
+++ linux-2.4.29-pre3/drivers/char/serial.c	2004-12-22 16:06:16.413802664 +0000
@@ -1068,17 +1068,15 @@ static void do_serial_bh(void)
 static void do_softint(void *private_)
 {
 	struct async_struct	*info = (struct async_struct *) private_;
-	struct tty_struct	*tty;
-	
+	struct tty_struct       *tty;
+
 	tty = info->tty;
 	if (!tty)
 		return;
 
 	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup)(tty);
-		wake_up_interruptible(&tty->write_wait);
+		tty_wakeup(tty);
+		
 #ifdef SERIAL_HAVE_POLL_WAIT
 		wake_up_interruptible(&tty->poll_wait);
 #endif
@@ -1976,13 +1974,10 @@ static void rs_flush_buffer(struct tty_s
 	save_flags(flags); cli();
 	info->xmit.head = info->xmit.tail = 0;
 	restore_flags(flags);
-	wake_up_interruptible(&tty->write_wait);
 #ifdef SERIAL_HAVE_POLL_WAIT
 	wake_up_interruptible(&tty->poll_wait);
 #endif
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
+	tty_wakeup(tty);
 }
 
 /*
@@ -2845,8 +2840,8 @@ static void rs_close(struct tty_struct *
 	 * the line discipline to only process XON/XOFF characters.
 	 */
 	tty->closing = 1;
-	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
-		tty_wait_until_sent(tty, info->closing_wait);
+	if (state->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, state->closing_wait);
 	/*
 	 * At this point we stop accepting input.  To do this, we
 	 * disable the receive line status interrupts, and tell the
@@ -2867,15 +2862,14 @@ static void rs_close(struct tty_struct *
 	shutdown(info);
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	tty_ldisc_flush(tty);
 	tty->closing = 0;
 	info->event = 0;
 	info->tty = 0;
 	if (info->blocked_open) {
-		if (info->close_delay) {
+		if (state->close_delay) {
 			set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout(info->close_delay);
+			schedule_timeout(state->close_delay);
 		}
 		wake_up_interruptible(&info->open_wait);
 	}
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/serial167.c linux-2.4.29-pre3/drivers/char/serial167.c
--- linux-2.4.28/drivers/char/serial167.c	2002-11-28 23:53:12.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/serial167.c	2004-12-22 16:06:34.070118496 +0000
@@ -773,11 +773,7 @@ do_softint(void *private_)
 	wake_up_interruptible(&info->open_wait);
     }
     if (test_and_clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) {
-	if((tty->flags & (1<< TTY_DO_WRITE_WAKEUP))
-	&& tty->ldisc.write_wakeup){
-	    (tty->ldisc.write_wakeup)(tty);
-	}
-	wake_up_interruptible(&tty->write_wait);
+	tty_wakeup(tty);
     }
 } /* do_softint */
 
@@ -1357,9 +1353,7 @@ cy_flush_buffer(struct tty_struct *tty)
 	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
     restore_flags(flags);
     wake_up_interruptible(&tty->write_wait);
-    if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP))
-    && tty->ldisc.write_wakeup)
-	(tty->ldisc.write_wakeup)(tty);
+    tty_wakeup(tty);
 } /* cy_flush_buffer */
 
 
@@ -1916,18 +1910,9 @@ cy_close(struct tty_struct * tty, struct
     shutdown(info);
     if (tty->driver.flush_buffer)
 	tty->driver.flush_buffer(tty);
-    if (tty->ldisc.flush_buffer)
-	tty->ldisc.flush_buffer(tty);
+    tty_ldisc_flush(tty);
     info->event = 0;
     info->tty = 0;
-    if (tty->ldisc.num != ldiscs[N_TTY].num) {
-	if (tty->ldisc.close)
-	    (tty->ldisc.close)(tty);
-	tty->ldisc = ldiscs[N_TTY];
-	tty->termios->c_line = N_TTY;
-	if (tty->ldisc.open)
-	    (tty->ldisc.open)(tty);
-    }
     if (info->blocked_open) {
 	if (info->close_delay) {
 	    current->state = TASK_INTERRUPTIBLE;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/serial_amba.c linux-2.4.29-pre3/drivers/char/serial_amba.c
--- linux-2.4.28/drivers/char/serial_amba.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/serial_amba.c	2004-12-22 16:05:37.349741304 +0000
@@ -569,10 +569,7 @@ static void ambauart_tasklet_action(unsi
 	if (!tty || !test_and_clear_bit(EVT_WRITE_WAKEUP, &info->event))
 		return;
 
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
-	wake_up_interruptible(&tty->write_wait);
+	tty_wakeup(tty);
 }
 
 static int ambauart_startup(struct amba_info *info)
@@ -958,10 +955,7 @@ static void ambauart_flush_buffer(struct
 	save_flags(flags); cli();
 	info->xmit.head = info->xmit.tail = 0;
 	restore_flags(flags);
-	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
+	tty_wakeup(tty);
 }
 
 /*
@@ -1459,8 +1453,7 @@ static void ambauart_close(struct tty_st
 	ambauart_shutdown(info);
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	tty_ldisc_flush(tty);
 	tty->closing = 0;
 	info->event = 0;
 	info->tty = NULL;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/serial_tx3912.c linux-2.4.29-pre3/drivers/char/serial_tx3912.c
--- linux-2.4.28/drivers/char/serial_tx3912.c	2003-08-25 11:44:41.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/serial_tx3912.c	2004-12-22 16:06:53.532159816 +0000
@@ -127,12 +127,9 @@ static inline void transmit_char_pio(str
 	}
 	
         if (port->gs.xmit_cnt <= port->gs.wakeup_chars) {
-                if ((port->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-                    port->gs.tty->ldisc.write_wakeup)
-                        (port->gs.tty->ldisc.write_wakeup)(port->gs.tty);
+		tty_wakeup(port->gs.tty);
                 rs_dprintk(TX3912_UART_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n",
                             port->gs.wakeup_chars); 
-                wake_up_interruptible(&port->gs.tty->write_wait);
        	}	
 }
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/serial_txx927.c linux-2.4.29-pre3/drivers/char/serial_txx927.c
--- linux-2.4.28/drivers/char/serial_txx927.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/serial_txx927.c	2004-12-22 16:06:25.971349696 +0000
@@ -535,10 +535,7 @@ static void do_softint(void *private_)
 		return;
 
 	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup)(tty);
-		wake_up_interruptible(&tty->write_wait);
+		tty_wakeup(tty);
 #ifdef SERIAL_HAVE_POLL_WAIT
 		wake_up_interruptible(&tty->poll_wait);
 #endif                                                    
@@ -1104,13 +1101,10 @@ static void rs_flush_buffer(struct tty_s
 	save_flags(flags); cli();
 	info->xmit.head = info->xmit.tail = 0;
 	restore_flags(flags);
-	wake_up_interruptible(&tty->write_wait);
 #ifdef SERIAL_HAVE_POLL_WAIT
 	wake_up_interruptible(&tty->poll_wait);
 #endif
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
+	tty_wakeup(tty);
 }
 
 /*
@@ -1442,8 +1436,8 @@ static void rs_close(struct tty_struct *
 	 * the line discipline to only process XON/XOFF characters.
 	 */
 	tty->closing = 1;
-	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
-		tty_wait_until_sent(tty, info->closing_wait);
+	if (state->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, state->closing_wait);
 	/*
 	 * At this point we stop accepting input.  To do this, we
 	 * disable the receive line status interrupts, and tell the
@@ -1465,15 +1459,14 @@ static void rs_close(struct tty_struct *
 	shutdown(info);
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	tty_ldisc_flush(tty);
 	tty->closing = 0;
 	info->event = 0;
 	info->tty = 0;
 	if (info->blocked_open) {
-		if (info->close_delay) {
+		if (state->close_delay) {
 			current->state = TASK_INTERRUPTIBLE;
-			schedule_timeout(info->close_delay);
+			schedule_timeout(state->close_delay);
 		}
 		wake_up_interruptible(&info->open_wait);
 	}
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/sgiserial.c linux-2.4.29-pre3/drivers/char/sgiserial.c
--- linux-2.4.28/drivers/char/sgiserial.c	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/sgiserial.c	2004-12-22 16:06:05.460467824 +0000
@@ -1498,10 +1498,10 @@ static void rs_close(struct tty_struct *
 	tty->closing = 0;
 	info->event = 0;
 	info->tty = 0;
-	if (tty->ldisc.num != ldiscs[N_TTY].num) {
+	if (tty->ldisc.num != N_TTY) {
 		if (tty->ldisc.close)
 			(tty->ldisc.close)(tty);
-		tty->ldisc = ldiscs[N_TTY];
+		tty->ldisc = *(tty_ldisc_get(N_TTY));
 		tty->termios->c_line = N_TTY;
 		if (tty->ldisc.open)
 			(tty->ldisc.open)(tty);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/sh-sci.c linux-2.4.29-pre3/drivers/char/sh-sci.c
--- linux-2.4.28/drivers/char/sh-sci.c	2003-11-28 18:26:20.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/sh-sci.c	2004-12-22 16:07:42.588702088 +0000
@@ -1021,10 +1021,7 @@ static void do_softint(void *private_)
 		return;
 
 	if (test_and_clear_bit(SCI_EVENT_WRITE_WAKEUP, &port->event)) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup)(tty);
-		wake_up_interruptible(&tty->write_wait);
+		tty_wakeup(tty);
 	}
 }
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/specialix.c linux-2.4.29-pre3/drivers/char/specialix.c
--- linux-2.4.28/drivers/char/specialix.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/specialix.c	2004-12-22 16:07:35.365800136 +0000
@@ -1579,8 +1579,7 @@ static void sx_close(struct tty_struct *
 	sx_shutdown_port(bp, port);
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	tty_ldisc_flush(tty);
 	tty->closing = 0;
 	port->event = 0;
 	port->tty = 0;
@@ -1758,10 +1757,7 @@ static void sx_flush_buffer(struct tty_s
 	port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
 	restore_flags(flags);
 	
-	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
+	tty_wakeup(tty);
 }
 
 
@@ -2211,12 +2207,8 @@ static void do_softint(void *private_)
 	if(!(tty = port->tty)) 
 		return;
 
-	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup)(tty);
-		wake_up_interruptible(&tty->write_wait);
-	}
+	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) 
+		tty_wakeup(tty);
 }
 
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/stallion.c linux-2.4.29-pre3/drivers/char/stallion.c
--- linux-2.4.28/drivers/char/stallion.c	2002-11-28 23:53:12.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/stallion.c	2004-12-22 16:05:58.020598856 +0000
@@ -3,7 +3,7 @@
 /*
  *	stallion.c  -- stallion multiport serial driver.
  *
- *	Copyright (C) 1996-1999  Stallion Technologies (support@stallion.oz.au).
+ *	Copyright (C) 1996-1999  Stallion Technologies
  *	Copyright (C) 1994-1996  Greg Ungerer.
  *
  *	This code is loosely based on the Linux serial driver, written by
@@ -1238,8 +1238,7 @@ static void stl_close(struct tty_struct 
 		portp->tx.tail = (char *) NULL;
 	}
 	set_bit(TTY_IO_ERROR, &tty->flags);
-	if (tty->ldisc.flush_buffer)
-		(tty->ldisc.flush_buffer)(tty);
+	tty_ldisc_flush(tty);
 
 	tty->closing = 0;
 	portp->tty = (struct tty_struct *) NULL;
@@ -1850,10 +1849,7 @@ static void stl_flushbuffer(struct tty_s
 		return;
 
 	stl_flush(portp);
-	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
+	tty_wakeup(tty);
 }
 
 /*****************************************************************************/
@@ -2224,10 +2220,7 @@ static void stl_offintr(void *private)
 
 	lock_kernel();
 	if (test_bit(ASYI_TXLOW, &portp->istate)) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup)(tty);
-		wake_up_interruptible(&tty->write_wait);
+		tty_wakeup(tty);
 	}
 	if (test_bit(ASYI_DCDCHANGE, &portp->istate)) {
 		clear_bit(ASYI_DCDCHANGE, &portp->istate);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/sx.c linux-2.4.29-pre3/drivers/char/sx.c
--- linux-2.4.28/drivers/char/sx.c	2003-06-13 14:51:33.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/sx.c	2004-12-22 16:06:30.056728624 +0000
@@ -1057,9 +1057,7 @@ static void sx_transmit_chars (struct sx
 	}
 
 	if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.tty) {
-		if ((port->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    port->gs.tty->ldisc.write_wakeup)
-			(port->gs.tty->ldisc.write_wakeup)(port->gs.tty);
+		tty_wakeup(port->gs.tty);
 		sx_dprintk (SX_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n",
 		            port->gs.wakeup_chars); 
 		wake_up_interruptible(&port->gs.tty->write_wait);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/synclink.c linux-2.4.29-pre3/drivers/char/synclink.c
--- linux-2.4.28/drivers/char/synclink.c	2003-11-28 18:26:20.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/synclink.c	2004-12-22 16:06:24.575561888 +0000
@@ -1011,6 +1011,29 @@ static inline int mgsl_paranoia_check(st
 	return 0;
 }
 
+/**
+ * line discipline callback wrappers
+ *
+ * The wrappers maintain line discipline references
+ * while calling into the line discipline.
+ *
+ * ldisc_receive_buf  - pass receive data to line discipline
+ */
+
+static void ldisc_receive_buf(struct tty_struct *tty,
+			      const __u8 *data, char *flags, int count)
+{
+	struct tty_ldisc *ld;
+	if (!tty)
+		return;
+	ld = tty_ldisc_ref(tty);
+	if (ld) {
+		if (ld->receive_buf)
+			ld->receive_buf(tty, data, flags, count);
+		tty_ldisc_deref(ld);
+	}
+}
+
 /* mgsl_stop()		throttle (stop) transmitter
  * 	
  * Arguments:		tty	pointer to tty info structure
@@ -1170,14 +1193,7 @@ void mgsl_bh_transmit(struct mgsl_struct
 			__FILE__,__LINE__,info->device_name);
 
 	if (tty) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup) {
-			if ( debug_level >= DEBUG_LEVEL_BH )
-				printk( "%s(%d):calling ldisc.write_wakeup on %s\n",
-					__FILE__,__LINE__,info->device_name);
-			(tty->ldisc.write_wakeup)(tty);
-		}
-		wake_up_interruptible(&tty->write_wait);
+		tty_wakeup(tty);
 	}
 
 	/* if transmitter idle and loopmode_send_done_requested
@@ -2433,12 +2449,8 @@ static void mgsl_flush_buffer(struct tty
 	del_timer(&info->tx_timer);	
 	spin_unlock_irqrestore(&info->irq_spinlock,flags);
 	
-	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
-		
-}	/* end of mgsl_flush_buffer() */
+	tty_wakeup(tty);
+}
 
 /* mgsl_send_xchar()
  *
@@ -3342,9 +3354,8 @@ static void mgsl_close(struct tty_struct
 
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-		
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	
+	tty_ldisc_flush(tty);
 		
 	shutdown(info);
 	
@@ -7007,11 +7018,7 @@ int mgsl_get_rx_frame(struct mgsl_struct
 			} 
 			else
 #endif
-			{
-				/* Call the line discipline receive callback directly. */
-				if ( tty && tty->ldisc.receive_buf )
-				tty->ldisc.receive_buf(tty, info->intermediate_rxbuffer, info->flag_buf, framesize);
-			}
+				ldisc_receive_buf(tty, info->intermediate_rxbuffer, info->flag_buf, framesize);
 		}
 	}
 	/* Free the buffers used by this frame. */
@@ -7183,9 +7190,7 @@ int mgsl_get_raw_rx_frame(struct mgsl_st
 			memcpy( info->intermediate_rxbuffer, pBufEntry->virt_addr, framesize);
 			info->icount.rxok++;
 
-			/* Call the line discipline receive callback directly. */
-			if ( tty && tty->ldisc.receive_buf )
-				tty->ldisc.receive_buf(tty, info->intermediate_rxbuffer, info->flag_buf, framesize);
+			ldisc_receive_buf(tty, info->intermediate_rxbuffer, info->flag_buf, framesize);
 		}
 
 		/* Free the buffers used by this frame. */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/synclinkmp.c linux-2.4.29-pre3/drivers/char/synclinkmp.c
--- linux-2.4.28/drivers/char/synclinkmp.c	2004-12-22 16:17:16.314482512 +0000
+++ linux-2.4.29-pre3/drivers/char/synclinkmp.c	2004-12-22 16:06:39.345316544 +0000
@@ -735,6 +735,29 @@ static inline int sanity_check(SLMP_INFO
 	return 0;
 }
 
+/**
+ * line discipline callback wrappers
+ *
+ * The wrappers maintain line discipline references
+ * while calling into the line discipline.
+ *
+ * ldisc_receive_buf  - pass receive data to line discipline
+ */
+
+static void ldisc_receive_buf(struct tty_struct *tty,
+			      const __u8 *data, char *flags, int count)
+{
+	struct tty_ldisc *ld;
+	if (!tty)
+		return;
+	ld = tty_ldisc_ref(tty);
+	if (ld) {
+		if (ld->receive_buf)
+			ld->receive_buf(tty, data, flags, count);
+		tty_ldisc_deref(ld);
+	}
+}
+
 /* tty callbacks */
 
 /* Called when a port is opened.  Init and enable port.
@@ -906,8 +929,7 @@ static void close(struct tty_struct *tty
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
 
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	tty_ldisc_flush(tty);
 
 	shutdown(info);
 
@@ -1315,9 +1337,7 @@ static void flush_buffer(struct tty_stru
 	spin_unlock_irqrestore(&info->lock,flags);
 
 	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
+	tty_wakeup(tty);
 }
 
 /* throttle (stop) transmitter
@@ -1983,13 +2003,7 @@ void bh_transmit(SLMP_INFO *info)
 			__FILE__,__LINE__,info->device_name);
 
 	if (tty) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup) {
-			if ( debug_level >= DEBUG_LEVEL_BH )
-				printk( "%s(%d):%s calling ldisc.write_wakeup\n",
-					__FILE__,__LINE__,info->device_name);
-			(tty->ldisc.write_wakeup)(tty);
-		}
+		tty_wakeup(tty);
 		wake_up_interruptible(&tty->write_wait);
 	}
 }
@@ -4989,15 +5003,8 @@ CheckAgain:
 			}
 			else
 #endif
-			{
-				if ( tty && tty->ldisc.receive_buf ) {
-					/* Call the line discipline receive callback directly. */
-					tty->ldisc.receive_buf(tty,
-						info->tmp_rx_buf,
-						info->flag_buf,
-						framesize);
-				}
-			}
+				ldisc_receive_buf(tty,info->tmp_rx_buf,
+						  info->flag_buf, framesize);
 		}
 	}
 	/* Free the buffers used by this frame. */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/tty_io.c linux-2.4.29-pre3/drivers/char/tty_io.c
--- linux-2.4.28/drivers/char/tty_io.c	2004-12-22 16:17:16.325480840 +0000
+++ linux-2.4.29-pre3/drivers/char/tty_io.c	2004-12-22 16:07:00.588087152 +0000
@@ -120,7 +120,6 @@ extern void disable_early_printk(void);
 
 struct termios tty_std_termios;		/* for the benefit of tty drivers  */
 struct tty_driver *tty_drivers;		/* linked list of tty drivers */
-struct tty_ldisc ldiscs[NR_LDISCS];	/* line disc dispatch table	*/
 
 #ifdef CONFIG_UNIX98_PTYS
 extern struct tty_driver ptm_driver[];	/* Unix98 pty masters; for /dev/ptmx */
@@ -260,63 +259,315 @@ static int check_tty_count(struct tty_st
 	return 0;
 }
 
+/*
+ *     This is probably overkill for real world processors but
+ *     they are not on hot paths so a little discipline won't do
+ *     any harm.
+ */    
+
+static void tty_set_termios_ldisc(struct tty_struct *tty, int num)
+{
+	down(&tty->termios_sem);
+	tty->termios->c_line = num;
+	up(&tty->termios_sem);
+}
+
+/*
+ *     This guards the refcounted line discipline lists. The lock
+ *     must be taken with irqs off because there are hangup path
+ *     callers who will do ldisc lookups and cannot sleep.
+ */
+
+spinlock_t tty_ldisc_lock = SPIN_LOCK_UNLOCKED;
+DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait);
+struct tty_ldisc tty_ldiscs[NR_LDISCS]; /* line disc dispatch table     */
+
 int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc)
 {
+
+	unsigned long flags;
+	int ret = 0;
+
 	if (disc < N_TTY || disc >= NR_LDISCS)
 		return -EINVAL;
-	
+
+	spin_lock_irqsave(&tty_ldisc_lock, flags);
 	if (new_ldisc) {
-		ldiscs[disc] = *new_ldisc;
-		ldiscs[disc].flags |= LDISC_FLAG_DEFINED;
-		ldiscs[disc].num = disc;
-	} else
-		memset(&ldiscs[disc], 0, sizeof(struct tty_ldisc));
+		tty_ldiscs[disc] = *new_ldisc;
+		tty_ldiscs[disc].num = disc;
+		tty_ldiscs[disc].flags |= LDISC_FLAG_DEFINED;
+		tty_ldiscs[disc].refcount = 0;
+	} else {
+		if(tty_ldiscs[disc].refcount)
+			ret = -EBUSY;
+		else
+			tty_ldiscs[disc].flags &= ~LDISC_FLAG_DEFINED;
+        }
+	spin_unlock_irqrestore(&tty_ldisc_lock, flags);
 	
-	return 0;
+	return ret;
+
 }
 
+
 EXPORT_SYMBOL(tty_register_ldisc);
 
-/* Set the discipline of a tty line. */
+struct tty_ldisc *tty_ldisc_get(int disc)
+{
+	unsigned long flags;
+	struct tty_ldisc *ld;
+
+	if (disc < N_TTY || disc >= NR_LDISCS)
+		return NULL;
+
+	spin_lock_irqsave(&tty_ldisc_lock, flags);
+
+	ld = &tty_ldiscs[disc];
+	/* Check the entry is defined */
+	if(ld->flags & LDISC_FLAG_DEFINED)
+		ld->refcount++;
+	else
+		ld = NULL;
+	spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+	return ld;
+}
+
+EXPORT_SYMBOL_GPL(tty_ldisc_get);
+
+void tty_ldisc_put(int disc)
+{
+	struct tty_ldisc *ld;
+	unsigned long flags;
+
+	if (disc < N_TTY || disc >= NR_LDISCS)
+		BUG();
+
+	spin_lock_irqsave(&tty_ldisc_lock, flags);
+	ld = &tty_ldiscs[disc];
+	if(ld->refcount <= 0)
+		BUG();
+	ld->refcount--;
+	spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+}
+      
+EXPORT_SYMBOL_GPL(tty_ldisc_put);
+
+void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld)
+{
+	tty->ldisc = *ld;
+	tty->ldisc.refcount = 0;
+}
+
+/**
+ *     tty_ldisc_try           -       internal helper
+ *     @tty: the tty
+ *
+ *     Make a single attempt to grab and bump the refcount on
+ *     the tty ldisc. Return 0 on failure or 1 on success. This is
+ *     used to implement both the waiting and non waiting versions
+ *     of tty_ldisc_ref
+ */
+
+static int tty_ldisc_try(struct tty_struct *tty)
+{
+	unsigned long flags;
+	struct tty_ldisc *ld;
+	int ret = 0;
+
+	spin_lock_irqsave(&tty_ldisc_lock, flags);
+	ld = &tty->ldisc;
+	if(test_bit(TTY_LDISC, &tty->flags))
+	{
+		ld->refcount++;
+		ret = 1;
+	}
+	spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+	return ret;
+}
+
+/**
+ *     tty_ldisc_ref_wait      -       wait for the tty ldisc
+ *     @tty: tty device
+ *
+ *     Dereference the line discipline for the terminal and take a
+ *     reference to it. If the line discipline is in flux then
+ *     wait patiently until it changes.
+ *
+ *     Note: Must not be called from an IRQ/timer context. The caller
+ *     must also be careful not to hold other locks that will deadlock
+ *     against a discipline change, such as an existing ldisc reference
+ *     (which we check for)
+ */
+
+struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty)
+{
+	/* wait_event is a macro */
+	wait_event(tty_ldisc_wait, tty_ldisc_try(tty));
+	return &tty->ldisc;
+}
+
+EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait);
+
+/**
+ *     tty_ldisc_ref           -       get the tty ldisc
+ *     @tty: tty device
+ *
+ *     Dereference the line discipline for the terminal and take a
+ *     reference to it. If the line discipline is in flux then
+ *     return NULL. Can be called from IRQ and timer functions.
+ */
+
+struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty)
+{
+	if(tty_ldisc_try(tty))
+		return &tty->ldisc;
+	return NULL;
+}
+
+EXPORT_SYMBOL_GPL(tty_ldisc_ref);
+
+
+void tty_ldisc_deref(struct tty_ldisc *ld)
+{
+
+	unsigned long flags;
+
+	if(ld == NULL)
+		BUG();
+
+	spin_lock_irqsave(&tty_ldisc_lock, flags);
+	if(ld->refcount == 0)
+		printk(KERN_EMERG "tty_ldisc_deref: no references.\n");
+	else
+		ld->refcount--;
+	if(ld->refcount == 0)
+		wake_up(&tty_ldisc_wait);
+	spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+}
+
+EXPORT_SYMBOL_GPL(tty_ldisc_deref);
+
+/**
+  *     tty_ldisc_enable        -       allow ldisc use
+  *     @tty: terminal to activate ldisc on
+  *
+  *     Set the TTY_LDISC flag when the line discipline can be called
+  *     again. Do neccessary wakeups for existing sleepers.
+  *
+  *     Note: nobody should set this bit except via this function. Clearing
+  *     directly is allowed.
+  */
+
+static void tty_ldisc_enable(struct tty_struct *tty)
+{
+	set_bit(TTY_LDISC, &tty->flags);
+	wake_up(&tty_ldisc_wait);
+}
+
+/**
+ *     tty_set_ldisc           -       set line discipline
+ *     @tty: the terminal to set
+ *     @ldisc: the line discipline
+ *
+ *     Set the discipline of a tty line. Must be called from a process
+ *     context.
+ */
+
 static int tty_set_ldisc(struct tty_struct *tty, int ldisc)
 {
 	int	retval = 0;
 	struct	tty_ldisc o_ldisc;
 	char buf[64];
+	int work;
+	unsigned long flags;
+	struct tty_ldisc *ld;
 
 	if ((ldisc < N_TTY) || (ldisc >= NR_LDISCS))
 		return -EINVAL;
+
+restart:
+
+	if (tty->ldisc.num == ldisc)
+		return 0; /* We are already in the desired discipline */
+
+	ld = tty_ldisc_get(ldisc);
 	/* Eduardo Blanco <ejbs@cs.cs.com.uy> */
 	/* Cyrus Durgin <cider@speakeasy.org> */
-	if (!(ldiscs[ldisc].flags & LDISC_FLAG_DEFINED)) {
+	if (ld == NULL)
+	{
 		char modname [20];
-		sprintf(modname, "tty-ldisc-%d", ldisc);
-		request_module (modname);
+                sprintf(modname, "tty-ldisc-%d", ldisc);
+                request_module (modname);
+		ld = tty_ldisc_get(ldisc);
 	}
-	if (!(ldiscs[ldisc].flags & LDISC_FLAG_DEFINED))
+	
+	if (ld == NULL)
 		return -EINVAL;
 
-	if (tty->ldisc.num == ldisc)
-		return 0;	/* We are already in the desired discipline */
+	
 	o_ldisc = tty->ldisc;
-
 	tty_wait_until_sent(tty, 0);
+
+	/*
+	 *      Make sure we don't change while someone holds a
+	 *      reference to the line discipline. The TTY_LDISC bit
+	 *      prevents anyone taking a reference once it is clear.
+	 *      We need the lock to avoid racing reference takers.
+	 */
+
+	spin_lock_irqsave(&tty_ldisc_lock, flags);
+	if(tty->ldisc.refcount)
+	{
+		/* Free the new ldisc we grabbed. Must drop the lock
+		   first. */
+		spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+		tty_ldisc_put(ldisc);
+		/*
+		 * There are several reasons we may be busy, including
+		 * random momentary I/O traffic. We must therefore
+		 * retry. We could distinguish between blocking ops
+		 * and retries if we made tty_ldisc_wait() smarter. That
+		 * is up for discussion.
+		 */
+		if(wait_event_interruptible(tty_ldisc_wait, tty->ldisc.refcount == 0) < 0)
+			return -ERESTARTSYS;
+		goto restart;
+	}
+	clear_bit(TTY_LDISC, &tty->flags);
+	clear_bit(TTY_DONT_FLIP, &tty->flags);
+	spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+
+	/*
+	 *      From this point on we know nobody has an ldisc
+	 *      usage reference, nor can they obtain one until
+	 *      we say so later on.
+	 */
+
+	/*
+	 * Wait for ->hangup_work and ->flip.work handlers to terminate
+	 */
+	run_task_queue(&tq_timer);
+	flush_scheduled_tasks();
 	
 	/* Shutdown the current discipline. */
 	if (tty->ldisc.close)
 		(tty->ldisc.close)(tty);
 
 	/* Now set up the new line discipline. */
-	tty->ldisc = ldiscs[ldisc];
-	tty->termios->c_line = ldisc;
+	tty_ldisc_assign(tty, ld);
+	tty_set_termios_ldisc(tty, ldisc);
 	if (tty->ldisc.open)
 		retval = (tty->ldisc.open)(tty);
 	if (retval < 0) {
-		tty->ldisc = o_ldisc;
-		tty->termios->c_line = tty->ldisc.num;
+		tty_ldisc_put(ldisc);
+		/* There is an outstanding reference here so this is safe */
+		tty_ldisc_assign(tty, tty_ldisc_get(o_ldisc.num));
+		tty_set_termios_ldisc(tty, tty->ldisc.num);
 		if (tty->ldisc.open && (tty->ldisc.open(tty) < 0)) {
-			tty->ldisc = ldiscs[N_TTY];
-			tty->termios->c_line = N_TTY;
+			tty_ldisc_put(o_ldisc.num);
+			/* This driver is always present */
+			tty_ldisc_assign(tty, tty_ldisc_get(N_TTY));
+			tty_set_termios_ldisc(tty, N_TTY);
 			if (tty->ldisc.open) {
 				int r = tty->ldisc.open(tty);
 
@@ -327,8 +578,21 @@ static int tty_set_ldisc(struct tty_stru
 			}
 		}
 	}
+	/* At this point we hold a reference to the new ldisc and a
+	    reference to the old ldisc. If we ended up flipping back
+	    to the existing ldisc we have two references to it */
+
 	if (tty->ldisc.num != o_ldisc.num && tty->driver.set_ldisc)
 		tty->driver.set_ldisc(tty);
+
+	tty_ldisc_put(o_ldisc.num);
+
+	/*
+	 *      Allow ldisc referencing to occur as soon as the driver
+	 *      ldisc callback completes.
+	 */
+	tty_ldisc_enable(tty);
+
 	return retval;
 }
 
@@ -430,11 +694,45 @@ static struct file_operations hung_up_tt
 
 static spinlock_t redirect_lock = SPIN_LOCK_UNLOCKED;
 static struct file *redirect;
-/*
- * This can be called by the "eventd" kernel thread.  That is process synchronous,
- * but doesn't hold any locks, so we need to make sure we have the appropriate
- * locks for what we're doing..
- */
+
+/**
+  *     tty_wakeup      -       request more data
+  *     @tty: terminal
+  *
+  *     Internal and external helper for wakeups of tty. This function
+  *     informs the line discipline if present that the driver is ready\
+  *     to receive more output data.
+  */
+
+void tty_wakeup(struct tty_struct *tty)
+{
+	struct tty_ldisc *ld;
+
+	if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) {
+		ld = tty_ldisc_ref(tty);
+		if(ld) {
+			if(ld->write_wakeup)
+				ld->write_wakeup(tty);
+			tty_ldisc_deref(ld);
+		}
+	}
+	wake_up_interruptible(&tty->write_wait);
+}
+
+EXPORT_SYMBOL_GPL(tty_wakeup);
+
+void tty_ldisc_flush(struct tty_struct *tty)
+{
+	struct tty_ldisc *ld = tty_ldisc_ref(tty);
+	if(ld) {
+		if(ld->flush_buffer)
+			ld->flush_buffer(tty);
+		tty_ldisc_deref(ld);
+	}
+}
+
+EXPORT_SYMBOL_GPL(tty_ldisc_flush);
+
 void do_tty_hangup(void *data)
 {
 	struct tty_struct *tty = (struct tty_struct *) data;
@@ -442,6 +740,7 @@ void do_tty_hangup(void *data)
 	struct file *f = NULL;
 	struct task_struct *p;
 	struct list_head *l;
+	struct tty_ldisc *ld;
 	int    closecount = 0, n;
 
 	if (!tty)
@@ -475,20 +774,22 @@ void do_tty_hangup(void *data)
 	file_list_unlock();
 	
 	/* FIXME! What are the locking issues here? This may me overdoing things.. */
+	ld = tty_ldisc_ref(tty);
+	if(ld != NULL)	
 	{
-		unsigned long flags;
-
-		save_flags(flags); cli();
-		if (tty->ldisc.flush_buffer)
-			tty->ldisc.flush_buffer(tty);
+		if (ld->flush_buffer)
+			ld->flush_buffer(tty);
 		if (tty->driver.flush_buffer)
 			tty->driver.flush_buffer(tty);
-		if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) &&
-		    tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup)(tty);
-		restore_flags(flags);
+		if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) && ld->write_wakeup)
+			ld->write_wakeup(tty);
+		if (ld->hangup)
+			ld->hangup(tty);
 	}
 
+	/* FIXME: Once we trust the LDISC code better we can wait here for
+	   ldisc completion and fix the driver call race */
+
 	wake_up_interruptible(&tty->write_wait);
 	wake_up_interruptible(&tty->read_wait);
 
@@ -496,21 +797,19 @@ void do_tty_hangup(void *data)
 	 * Shutdown the current line discipline, and reset it to
 	 * N_TTY.
 	 */
+
 	if (tty->driver.flags & TTY_DRIVER_RESET_TERMIOS)
-		*tty->termios = tty->driver.init_termios;
-	if (tty->ldisc.num != ldiscs[N_TTY].num) {
-		if (tty->ldisc.close)
-			(tty->ldisc.close)(tty);
-		tty->ldisc = ldiscs[N_TTY];
-		tty->termios->c_line = N_TTY;
-		if (tty->ldisc.open) {
-			int i = (tty->ldisc.open)(tty);
-			if (i < 0)
-				printk(KERN_ERR "do_tty_hangup: N_TTY open: "
-						"error %d\n", -i);
-		}
+	{
+		down(&tty->termios_sem);
+                *tty->termios = tty->driver.init_termios;
+		up(&tty->termios_sem);
 	}
-	
+
+	/* Defer ldisc switch */
+	/* tty_deferred_ldisc_switch(N_TTY)
+	   This should get done automatically when the port closes and
+	   tty_release is called */
+
 	read_lock(&tasklist_lock);
  	for_each_task(p) {
 		if ((tty->session > 0) && (p->session == tty->session) &&
@@ -541,6 +840,17 @@ void do_tty_hangup(void *data)
 				tty->driver.close(tty, cons_filp);
 	} else if (tty->driver.hangup)
 		(tty->driver.hangup)(tty);
+
+	/* We don't want to have driver/ldisc interactions beyond
+	   the ones we did here. The driver layer expects no
+	   calls after ->hangup() from the ldisc side. However we
+	   can't yet guarantee all that */
+
+	set_bit(TTY_HUPPED, &tty->flags);
+	if(ld) {
+		tty_ldisc_enable(tty);
+		tty_ldisc_deref(ld);
+	}
 	unlock_kernel();
 	if (f)
 		fput(f);
@@ -644,10 +954,8 @@ void start_tty(struct tty_struct *tty)
 	}
 	if (tty->driver.start)
 		(tty->driver.start)(tty);
-	if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
-	wake_up_interruptible(&tty->write_wait);
+	/* If we have a running line discipline it may need kicking */
+	tty_wakeup(tty);
 }
 
 static ssize_t tty_read(struct file * file, char * buf, size_t count, 
@@ -656,6 +964,7 @@ static ssize_t tty_read(struct file * fi
 	int i;
 	struct tty_struct * tty;
 	struct inode *inode;
+	struct tty_ldisc *ld;
 
 	/* Can't seek (pread) on ttys.  */
 	if (ppos != &file->f_pos)
@@ -684,11 +993,15 @@ static ssize_t tty_read(struct file * fi
 			return -ERESTARTSYS;
 		}
 #endif
+	/* We want to wait for the line discipline to sort out in this
+	   situation */
+	ld = tty_ldisc_ref_wait(tty);
 	lock_kernel();
-	if (tty->ldisc.read)
-		i = (tty->ldisc.read)(tty,file,buf,count);
+	if (ld->read)
+		i = (ld->read)(tty,file,buf,count);
 	else
 		i = -EIO;
+	tty_ldisc_deref(ld);
 	unlock_kernel();
 	if (i > 0)
 		inode->i_atime = CURRENT_TIME;
@@ -757,6 +1070,8 @@ static ssize_t tty_write(struct file * f
 	int is_console;
 	struct tty_struct * tty;
 	struct inode *inode = file->f_dentry->d_inode;
+	ssize_t ret;
+	struct tty_ldisc *ld;
 
 	/* Can't seek (pwrite) on ttys.  */
 	if (ppos != &file->f_pos)
@@ -803,13 +1118,19 @@ static ssize_t tty_write(struct file * f
 		}
 	}
 #endif
-	if (!tty->ldisc.write)
-		return -EIO;
-	return do_tty_write(tty->ldisc.write, tty, file,
-			    (const unsigned char *)buf, count);
+
+	ld = tty_ldisc_ref_wait(tty);
+	if (!ld->write)
+		ret = -EIO;
+	else
+		ret = do_tty_write(ld->write, tty, file,
+				(const unsigned char __user *)buf, count);
+	tty_ldisc_deref(ld);
+	return ret;
 }
 
-/* Semaphore to protect creating and releasing a tty */
+/* Semaphore to protect creating and releasing a tty. This is shared with
+   vt.c for deeply disgusting hack reasons */
 static DECLARE_MUTEX(tty_sem);
 
 static void down_tty_sem(int index)
@@ -971,7 +1292,10 @@ static int init_dev(kdev_t device, struc
 				(tty->ldisc.close)(tty);
 			goto release_mem_out;
 		}
+		set_bit(TTY_LDISC, &o_tty->flags);
+		tty_ldisc_enable(o_tty);
 	}
+	tty_ldisc_enable(tty);
 	goto success;
 
 	/*
@@ -999,7 +1323,9 @@ fast_track:
 	}
 	tty->count++;
 	tty->driver = *driver; /* N.B. why do this every time?? */
-
+	/* FIXME */
+	if(!test_bit(TTY_LDISC, &tty->flags))
+		printk(KERN_ERR "init_dev but no ldisc\n");
 success:
 	*ret_tty = tty;
 	
@@ -1080,6 +1406,7 @@ static void release_dev(struct file * fi
 	int	pty_master, tty_closing, o_tty_closing, do_sleep;
 	int	idx;
 	char	buf[64];
+	unsigned long flags;
 	
 	tty = (struct tty_struct *)filp->private_data;
 	if (tty_paranoia_check(tty, filp->f_dentry->d_inode->i_rdev, "release_dev"))
@@ -1272,24 +1599,59 @@ static void release_dev(struct file * fi
 #endif
 
 	/*
+	 * Prevent flush_to_ldisc() from rescheduling the work for later.  Then
+	 * kill any delayed work. As this is the final close it does not
+	 * race with the set_ldisc code path.
+	 */
+	clear_bit(TTY_LDISC, &tty->flags);
+	clear_bit(TTY_DONT_FLIP, &tty->flags);
+
+	/*
+	 * Wait for ->hangup_work and ->flip.work handlers to terminate
+	 */
+
+	run_task_queue(&tq_timer);
+	flush_scheduled_tasks();
+
+	/*
+	 * Wait for any short term users (we know they are just driver
+         * side waiters as the file is closing so user count on the file
+         * side is zero.
+	 */
+
+	spin_lock_irqsave(&tty_ldisc_lock, flags);
+	while(tty->ldisc.refcount)
+	{
+		spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+		wait_event(tty_ldisc_wait, tty->ldisc.refcount == 0);
+		spin_lock_irqsave(&tty_ldisc_lock, flags);
+	}
+	spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+
+	/*
 	 * Shutdown the current line discipline, and reset it to N_TTY.
 	 * N.B. why reset ldisc when we're releasing the memory??
+	 * FIXME: this MUST get fixed for the new reflocking
 	 */
 	if (tty->ldisc.close)
 		(tty->ldisc.close)(tty);
-	tty->ldisc = ldiscs[N_TTY];
-	tty->termios->c_line = N_TTY;
+	tty_ldisc_put(tty->ldisc.num);
+
+	/*
+	 *      Switch the line discipline back
+	 */
+	tty_ldisc_assign(tty, tty_ldisc_get(N_TTY));
+	tty_set_termios_ldisc(tty,N_TTY); 
+
 	if (o_tty) {
+		/* FIXME: could o_tty be in setldisc here ? */
+		clear_bit(TTY_LDISC, &o_tty->flags);
 		if (o_tty->ldisc.close)
 			(o_tty->ldisc.close)(o_tty);
-		o_tty->ldisc = ldiscs[N_TTY];
+		tty_ldisc_put(o_tty->ldisc.num);
+		tty_ldisc_assign(o_tty, tty_ldisc_get(N_TTY));
+		tty_set_termios_ldisc(o_tty,N_TTY);
 	}
-	
-	/*
-	 * Make sure that the tty's task queue isn't activated. 
-	 */
-	run_task_queue(&tq_timer);
-	flush_scheduled_tasks();
 
 	/* 
 	 * The release_mem function takes care of the details of clearing
@@ -1464,14 +1826,18 @@ static int tty_release(struct inode * in
 static unsigned int tty_poll(struct file * filp, poll_table * wait)
 {
 	struct tty_struct * tty;
+	struct tty_ldisc *ld;
+	int ret = 0;
 
 	tty = (struct tty_struct *)filp->private_data;
 	if (tty_paranoia_check(tty, filp->f_dentry->d_inode->i_rdev, "tty_poll"))
 		return 0;
 
-	if (tty->ldisc.poll)
-		return (tty->ldisc.poll)(tty, filp, wait);
-	return 0;
+	ld = tty_ldisc_ref_wait(tty);
+	if (ld->poll)
+		ret = (ld->poll)(tty, filp, wait);
+	tty_ldisc_deref(ld);
+	return ret;
 }
 
 static int tty_fasync(int fd, struct file * filp, int on)
@@ -1505,12 +1871,15 @@ static int tty_fasync(int fd, struct fil
 static int tiocsti(struct tty_struct *tty, char * arg)
 {
 	char ch, mbz = 0;
+	struct tty_ldisc *ld;
 
 	if ((current->tty != tty) && !suser())
 		return -EPERM;
 	if (get_user(ch, arg))
 		return -EFAULT;
-	tty->ldisc.receive_buf(tty, &ch, &mbz, 1);
+	ld = tty_ldisc_ref_wait(tty);
+	ld->receive_buf(tty, &ch, &mbz, 1);
+	tty_ldisc_deref(ld);
 	return 0;
 }
 
@@ -1718,6 +2087,7 @@ int tty_ioctl(struct inode * inode, stru
 {
 	struct tty_struct *tty, *real_tty;
 	int retval;
+	struct tty_ldisc *ld;
 	
 	tty = (struct tty_struct *)file->private_data;
 	if (tty_paranoia_check(tty, inode->i_rdev, "tty_ioctl"))
@@ -1808,6 +2178,7 @@ int tty_ioctl(struct inode * inode, stru
 		case TIOCGSID:
 			return tiocgsid(tty, real_tty, (pid_t *) arg);
 		case TIOCGETD:
+			/* FIXME: check this is ok */
 			return put_user(tty->ldisc.num, (int *) arg);
 		case TIOCSETD:
 			return tiocsetd(tty, (int *) arg);
@@ -1841,16 +2212,19 @@ int tty_ioctl(struct inode * inode, stru
 			return send_break(tty, arg ? arg*(HZ/10) : HZ/4);
 	}
 	if (tty->driver.ioctl) {
-		int retval = (tty->driver.ioctl)(tty, file, cmd, arg);
+		retval = (tty->driver.ioctl)(tty, file, cmd, arg);
 		if (retval != -ENOIOCTLCMD)
 			return retval;
 	}
-	if (tty->ldisc.ioctl) {
-		int retval = (tty->ldisc.ioctl)(tty, file, cmd, arg);
-		if (retval != -ENOIOCTLCMD)
-			return retval;
+	ld = tty_ldisc_ref_wait(tty);
+	retval = -EINVAL;
+	if (ld->ioctl) {
+		retval = ld->ioctl(tty, file, cmd, arg);
+		if (retval == -ENOIOCTLCMD)
+			retval = -EINVAL;
 	}
-	return -EINVAL;
+	tty_ldisc_deref(ld);
+	return retval;
 }
 
 
@@ -1883,14 +2257,20 @@ static void __do_SAK(void *arg)
 	int session;
 	int		i;
 	struct file	*filp;
+	struct tty_ldisc *disc;
 	
 	if (!tty)
 		return;
 	session  = tty->session;
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	/* We don't want an ldisc switch during this */
+	disc = tty_ldisc_ref(tty);
+	if (disc && disc->flush_buffer)
+		disc->flush_buffer(tty);
+	tty_ldisc_deref(disc);
+
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
+
 	read_lock(&tasklist_lock);
 	for_each_task(p) {
 		if ((p->tty == tty) ||
@@ -1942,11 +2322,16 @@ static void flush_to_ldisc(void *private
 	unsigned char	*cp;
 	char		*fp;
 	int		count;
-	unsigned long flags;
+	unsigned long 	flags;
+	struct tty_ldisc *disc;
+
+	disc = tty_ldisc_ref(tty);
+	if (disc == NULL)       /*  !TTY_LDISC */
+		return;
 
 	if (test_bit(TTY_DONT_FLIP, &tty->flags)) {
 		queue_task(&tty->flip.tqueue, &tq_timer);
-		return;
+		goto out;
 	}
 	if (tty->flip.buf_num) {
 		cp = tty->flip.char_buf + TTY_FLIPBUF_SIZE;
@@ -1969,7 +2354,31 @@ static void flush_to_ldisc(void *private
 	tty->flip.count = 0;
 	restore_flags(flags);
 	
-	tty->ldisc.receive_buf(tty, cp, fp, count);
+	disc->receive_buf(tty, cp, fp, count);
+out:
+	tty_ldisc_deref(disc);
+}
+
+/*
+ *     Call the ldisc flush directly from a driver. This function may
+ *     return an error and need retrying by the user.
+ */
+
+int tty_push_data(struct tty_struct *tty, unsigned char *cp, unsigned char *fp, int count)
+{
+	int ret = 0;
+	struct tty_ldisc *disc;
+	
+	disc = tty_ldisc_ref(tty);
+	if(test_bit(TTY_DONT_FLIP, &tty->flags))
+		ret = -EAGAIN;
+	else if(disc == NULL)
+		ret = -EIO;
+	else
+		disc->receive_buf(tty, cp, fp, count);
+	tty_ldisc_deref(disc);
+	return ret;
+
 }
 
 /*
@@ -2032,13 +2441,14 @@ static void initialize_tty_struct(struct
 {
 	memset(tty, 0, sizeof(struct tty_struct));
 	tty->magic = TTY_MAGIC;
-	tty->ldisc = ldiscs[N_TTY];
+	tty_ldisc_assign(tty, tty_ldisc_get(N_TTY));
 	tty->pgrp = -1;
 	tty->flip.char_buf_ptr = tty->flip.char_buf;
 	tty->flip.flag_buf_ptr = tty->flip.flag_buf;
 	tty->flip.tqueue.routine = flush_to_ldisc;
 	tty->flip.tqueue.data = tty;
 	init_MUTEX(&tty->flip.pty_sem);
+	init_MUTEX(&tty->termios_sem);
 	init_waitqueue_head(&tty->write_wait);
 	init_waitqueue_head(&tty->read_wait);
 	tty->tq_hangup.routine = do_tty_hangup;
@@ -2217,7 +2627,7 @@ int tty_unregister_driver(struct tty_dri
 void __init console_init(void)
 {
 	/* Setup the default TTY line discipline. */
-	memset(ldiscs, 0, sizeof(ldiscs));
+	memset(tty_ldiscs, 0, NR_LDISCS*sizeof(struct tty_ldisc));
 	(void) tty_register_ldisc(N_TTY, &tty_ldisc_N_TTY);
 
 	/*
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/tty_ioctl.c linux-2.4.29-pre3/drivers/char/tty_ioctl.c
--- linux-2.4.28/drivers/char/tty_ioctl.c	2002-11-28 23:53:12.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/tty_ioctl.c	2004-12-22 16:07:54.564881432 +0000
@@ -96,8 +96,16 @@ static void change_termios(struct tty_st
 {
 	int canon_change;
 	struct termios old_termios = *tty->termios;
+	struct tty_ldisc *ld;
+
+	/*
+	 *      Perform the actual termios internal changes under lock.
+	 */
+
+	/* FIXME: we need to decide on some locking/ordering semantics
+	   for the set_termios notification eventually */
+	down(&tty->termios_sem);
 
-	cli();
 	*tty->termios = *new_termios;
 	unset_locked_termios(tty->termios, &old_termios, tty->termios_locked);
 	canon_change = (old_termios.c_lflag ^ tty->termios->c_lflag) & ICANON;
@@ -107,7 +115,6 @@ static void change_termios(struct tty_st
 		tty->canon_data = 0;
 		tty->erasing = 0;
 	}
-	sti();
 	if (canon_change && !L_ICANON(tty) && tty->read_cnt)
 		/* Get characters left over from canonical mode. */
 		wake_up_interruptible(&tty->read_wait);
@@ -134,13 +141,19 @@ static void change_termios(struct tty_st
 	if (tty->driver.set_termios)
 		(*tty->driver.set_termios)(tty, &old_termios);
 
-	if (tty->ldisc.set_termios)
-		(*tty->ldisc.set_termios)(tty, &old_termios);
+	ld = tty_ldisc_ref(tty);
+	if (ld != NULL) {
+		if (ld->set_termios)
+			(ld->set_termios)(tty, &old_termios);
+		tty_ldisc_deref(ld);
+	}
+	up(&tty->termios_sem);
 }
 
 static int set_termios(struct tty_struct * tty, unsigned long arg, int opt)
 {
 	struct termios tmp_termios;
+	struct tty_ldisc *ld;
 	int retval = tty_check_change(tty);
 
 	if (retval)
@@ -157,8 +170,13 @@ static int set_termios(struct tty_struct
 			return -EFAULT;
 	}
 
-	if ((opt & TERMIOS_FLUSH) && tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	ld = tty_ldisc_ref(tty);
+
+	if (ld != NULL) {
+		if ((opt & TERMIOS_FLUSH) && ld->flush_buffer)
+			ld->flush_buffer(tty);
+		tty_ldisc_deref(ld);
+	}
 
 	if (opt & TERMIOS_WAIT) {
 		tty_wait_until_sent(tty, 0);
@@ -223,12 +241,16 @@ static int get_sgflags(struct tty_struct
 static int get_sgttyb(struct tty_struct * tty, struct sgttyb * sgttyb)
 {
 	struct sgttyb tmp;
+	unsigned long flags;
 
+	down(&tty->termios_sem);
 	tmp.sg_ispeed = 0;
 	tmp.sg_ospeed = 0;
 	tmp.sg_erase = tty->termios->c_cc[VERASE];
 	tmp.sg_kill = tty->termios->c_cc[VKILL];
 	tmp.sg_flags = get_sgflags(tty);
+	up(&tty->termios_sem);
+
 	return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0;
 }
 
@@ -267,12 +289,14 @@ static int set_sgttyb(struct tty_struct 
 	retval = tty_check_change(tty);
 	if (retval)
 		return retval;
-	termios =  *tty->termios;
 	if (copy_from_user(&tmp, sgttyb, sizeof(tmp)))
 		return -EFAULT;
+	down(&tty->termios_sem);
+	termios =  *tty->termios;
 	termios.c_cc[VERASE] = tmp.sg_erase;
 	termios.c_cc[VKILL] = tmp.sg_kill;
 	set_sgflags(&termios, tmp.sg_flags);
+	up(&tty->termios_sem);
 	change_termios(tty, &termios);
 	return 0;
 }
@@ -362,6 +386,8 @@ int n_tty_ioctl(struct tty_struct * tty,
 {
 	struct tty_struct * real_tty;
 	int retval;
+	struct tty_ldisc *ld;
+	unsigned long flags;
 
 	if (tty->driver.type == TTY_DRIVER_TYPE_PTY &&
 	    tty->driver.subtype == PTY_TYPE_MASTER)
@@ -440,22 +466,26 @@ int n_tty_ioctl(struct tty_struct * tty,
 			retval = tty_check_change(tty);
 			if (retval)
 				return retval;
+
+			ld = tty_ldisc_ref(tty);
 			switch (arg) {
 			case TCIFLUSH:
-				if (tty->ldisc.flush_buffer)
-					tty->ldisc.flush_buffer(tty);
+				if (ld->flush_buffer)
+					ld->flush_buffer(tty);
 				break;
 			case TCIOFLUSH:
-				if (tty->ldisc.flush_buffer)
-					tty->ldisc.flush_buffer(tty);
+				if (ld->flush_buffer)
+					ld->flush_buffer(tty);
 				/* fall through */
 			case TCOFLUSH:
 				if (tty->driver.flush_buffer)
 					tty->driver.flush_buffer(tty);
 				break;
 			default:
+				tty_ldisc_deref(ld);
 				return -EINVAL;
 			}
+			tty_ldisc_deref(ld);
 			return 0;
 		case TIOCOUTQ:
 			return put_user(tty->driver.chars_in_buffer ?
@@ -501,9 +531,11 @@ int n_tty_ioctl(struct tty_struct * tty,
 		case TIOCSSOFTCAR:
 			if (get_user(arg, (unsigned int *) arg))
 				return -EFAULT;
+			down(&tty->termios_sem);
 			tty->termios->c_cflag =
 				((tty->termios->c_cflag & ~CLOCAL) |
 				 (arg ? CLOCAL : 0));
+			up(&tty->termios_sem);
 			return 0;
 		default:
 			return -ENOIOCTLCMD;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/vac-serial.c linux-2.4.29-pre3/drivers/char/vac-serial.c
--- linux-2.4.28/drivers/char/vac-serial.c	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/vac-serial.c	2004-12-22 16:07:06.266223944 +0000
@@ -1699,8 +1699,8 @@ static void rs_close(struct tty_struct *
 	 * the line discipline to only process XON/XOFF characters.
 	 */
 	tty->closing = 1;
-	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
-		tty_wait_until_sent(tty, info->closing_wait);
+	if (state->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, state->closing_wait);
 	/*
 	 * At this point we stop accepting input.  To do this, we
 	 * disable the receive line status interrupts, and tell the
@@ -1727,9 +1727,9 @@ static void rs_close(struct tty_struct *
 	info->event = 0;
 	info->tty = 0;
 	if (info->blocked_open) {
-		if (info->close_delay) {
+		if (state->close_delay) {
 			current->state = TASK_INTERRUPTIBLE;
-			schedule_timeout(info->close_delay);
+			schedule_timeout(state->close_delay);
 		}
 		wake_up_interruptible(&info->open_wait);
 	}
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/vme_scc.c linux-2.4.29-pre3/drivers/char/vme_scc.c
--- linux-2.4.28/drivers/char/vme_scc.c	2002-08-03 00:39:43.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/vme_scc.c	2004-12-22 16:05:31.877573200 +0000
@@ -569,12 +569,8 @@ static void scc_tx_int(int irq, void *da
 		SCCwrite(COMMAND_REG, CR_TX_PENDING_RESET);   /* disable tx_int on next tx underrun? */
 		port->gs.flags &= ~GS_TX_INTEN;
 	}
-	if (port->gs.tty && port->gs.xmit_cnt <= port->gs.wakeup_chars) {
-		if ((port->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-				port->gs.tty->ldisc.write_wakeup)
-			(port->gs.tty->ldisc.write_wakeup)(port->gs.tty);
-		wake_up_interruptible(&port->gs.tty->write_wait);
-	}
+	if (port->gs.tty && port->gs.xmit_cnt <= port->gs.wakeup_chars) 
+		tty_wakeup(port->gs.tty);
 
 	SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/char/vt.c linux-2.4.29-pre3/drivers/char/vt.c
--- linux-2.4.28/drivers/char/vt.c	2002-11-28 23:53:12.000000000 +0000
+++ linux-2.4.29-pre3/drivers/char/vt.c	2004-12-22 16:07:12.582263760 +0000
@@ -588,8 +588,7 @@ int vt_ioctl(struct tty_struct *tty, str
 		  default:
 			return -EINVAL;
 		}
-		if (tty->ldisc.flush_buffer)
-			tty->ldisc.flush_buffer(tty);
+		tty_ldisc_flush(tty);
 		return 0;
 
 	case KDGKBMODE:
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/hotplug/cpqphp_pci.c linux-2.4.29-pre3/drivers/hotplug/cpqphp_pci.c
--- linux-2.4.28/drivers/hotplug/cpqphp_pci.c	2003-11-28 18:26:20.000000000 +0000
+++ linux-2.4.29-pre3/drivers/hotplug/cpqphp_pci.c	2004-12-22 16:07:40.575008216 +0000
@@ -387,7 +387,7 @@ static int PCI_ScanBusNonBridge (u8 bus,
 
 static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev_num)
 {
-	u8 tdevice;
+	u16 tdevice;
 	u32 work;
 	u8 tbus;
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/i2c/i2c-core.c linux-2.4.29-pre3/drivers/i2c/i2c-core.c
--- linux-2.4.28/drivers/i2c/i2c-core.c	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-pre3/drivers/i2c/i2c-core.c	2004-12-22 16:05:49.938827472 +0000
@@ -901,7 +901,7 @@ int i2c_probe(struct i2c_adapter *adapte
 			if (addr == address_data->normal_i2c[i]) {
 				found = 1;
 				DEB2(printk(KERN_DEBUG "i2c-core.o: found normal i2c entry for adapter %d, "
-				            "addr %02x", adap_id,addr));
+				            "addr %02x\n", adap_id, addr));
 			}
 		}
 
@@ -1098,8 +1098,8 @@ static s32 i2c_smbus_xfer_emulated(struc
 	  need to use only one message; when reading, we need two. We initialize
 	  most things with sane defaults, to keep the code below somewhat
 	  simpler. */
-	unsigned char msgbuf0[34];
-	unsigned char msgbuf1[34];
+	unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+2];
+	unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2];
 	int num = read_write == I2C_SMBUS_READ?2:1;
 	struct i2c_msg msg[2] = { { addr, flags, 1, msgbuf0 }, 
 	                          { addr, flags | I2C_M_RD, 0, msgbuf1 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/i2c/i2c-proc.c linux-2.4.29-pre3/drivers/i2c/i2c-proc.c
--- linux-2.4.28/drivers/i2c/i2c-proc.c	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-pre3/drivers/i2c/i2c-proc.c	2004-12-22 16:06:47.477080328 +0000
@@ -152,7 +152,7 @@ int i2c_register_entry(struct i2c_client
 	id += 256;
 
 	len = 0;
-	while (ctl_template[len].procname)
+	while (ctl_template[len].ctl_name)
 		len++;
 	len += 7;
 	if (!(new_table = kmalloc(sizeof(ctl_table) * len, GFP_KERNEL))) {
@@ -540,7 +540,7 @@ int i2c_parse_reals(int *nrels, void *bu
 		/* Skip everything until we hit whitespace */
 		while (bufsize && 
 		       !((ret=get_user(nextchar, (char *) buffer))) &&
-		       isspace((int) nextchar)) {
+		       !isspace((int) nextchar)) {
 			bufsize--;
 			((char *) buffer)++;
 		}
@@ -762,7 +762,7 @@ int i2c_detect(struct i2c_adapter *adapt
 #ifdef DEBUG
 					printk
 					    (KERN_DEBUG "i2c-proc.o: found normal isa_range entry for adapter %d, "
-					     "addr %04x", adapter_id, addr);
+					     "addr %04x\n", adapter_id, addr);
 #endif
 					found = 1;
 				}
@@ -776,7 +776,7 @@ int i2c_detect(struct i2c_adapter *adapt
 #ifdef DEBUG
 					printk
 					    (KERN_DEBUG "i2c-proc.o: found normal i2c entry for adapter %d, "
-					     "addr %02x", adapter_id, addr);
+					     "addr %02x\n", adapter_id, addr);
 #endif
 				}
 			}
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/ide/raid/hptraid.c linux-2.4.29-pre3/drivers/ide/raid/hptraid.c
--- linux-2.4.28/drivers/ide/raid/hptraid.c	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-pre3/drivers/ide/raid/hptraid.c	2004-12-22 16:07:55.584726392 +0000
@@ -18,7 +18,11 @@
    Based on work done by Søren Schmidt for FreeBSD
 
    Changelog:
-   15.06.2003 wweissmann@gmx.at
+   19.08.2003 v0.03 wweissmann@gmx.at
+   	* register the raid volume only if all disks are available
+	* print a warning that raid-(0+)1 failover is not supported
+
+   15.06.2003 v0.02 wweissmann@gmx.at
    	* correct values of raid-1 superbock
 	* re-add check for availability of all disks
 	* fix offset bug in raid-1 (introduced in raid 0+1 implementation)
@@ -814,10 +818,6 @@ static int hptraid_init_one(int device, 
 			break;
 	}
 
-	/* Initialize the gendisk structure */
-	
-	ataraid_register_disk(device,raid[device].sectors);
-
 	/* Verify that we have all disks */
 
 	count=count_disks(raid+device);
@@ -844,7 +844,17 @@ static int hptraid_init_one(int device, 
 					return -ENODEV;
 				}
 			}
+			printk(KERN_WARNING "ataraid%i: raid-0+1 disk failover is not implemented!\n",
+					device);
 		}
+		else if (type == HPT_T_RAID_1) {
+			printk(KERN_WARNING "ataraid%i: raid-1 disk failover is not implemented!\n",
+					device);
+		}	
+		/* Initialize the gendisk structure */
+	
+		ataraid_register_disk(device,raid[device].sectors);
+
 		return 0;
 	}
 	
@@ -856,7 +866,7 @@ static int hptraid_init(void)
  	int retval=-ENODEV;
 	int device,i,count=0;
   	
-	printk(KERN_INFO "Highpoint HPT370 Softwareraid driver for linux version 0.02\n");
+	printk(KERN_INFO "Highpoint HPT370 Softwareraid driver for linux version 0.03\n");
 
 	for(i=0; oplist[i].op; i++) {
 		do
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/isdn/eicon/fourbri.c linux-2.4.29-pre3/drivers/isdn/eicon/fourbri.c
--- linux-2.4.28/drivers/isdn/eicon/fourbri.c	2001-09-30 19:26:05.000000000 +0000
+++ linux-2.4.29-pre3/drivers/isdn/eicon/fourbri.c	2004-12-22 16:06:54.602997024 +0000
@@ -337,7 +337,8 @@ static int diva_server_4bri_load(card_t 
 static int diva_server_4bri_start(card_t *card, byte *channels)
 {
 	byte *ctl;
-	byte *shared, i;
+	byte *shared;
+	int i;
 	int adapter_num;
 
 	DPRINTF(("divas: start Diva Server 4BRI"));
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/isdn/isdn_tty.c linux-2.4.29-pre3/drivers/isdn/isdn_tty.c
--- linux-2.4.28/drivers/isdn/isdn_tty.c	2001-12-21 17:41:54.000000000 +0000
+++ linux-2.4.29-pre3/drivers/isdn/isdn_tty.c	2004-12-22 16:07:15.144874184 +0000
@@ -321,10 +321,7 @@ isdn_tty_tint(modem_info * info)
 		info->send_outstanding++;
 		info->msr &= ~UART_MSR_CTS;
 		info->lsr &= ~UART_LSR_TEMT;
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup) (tty);
-		wake_up_interruptible(&tty->write_wait);
+		tty_wakeup(tty);
 		return;
 	}
 	if (slen < 0) {
@@ -1214,10 +1211,7 @@ isdn_tty_write(struct tty_struct *tty, i
 						/* If DLE decoding results in zero-transmit, but
 						 * c originally was non-zero, do a wakeup.
 						 */
-						if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-						 tty->ldisc.write_wakeup)
-							(tty->ldisc.write_wakeup) (tty);
-						wake_up_interruptible(&tty->write_wait);
+						tty_wakeup(tty);
 						info->msr |= UART_MSR_CTS;
 						info->lsr |= UART_LSR_TEMT;
 					}
@@ -1335,10 +1329,7 @@ isdn_tty_flush_buffer(struct tty_struct 
 	isdn_tty_cleanup_xmit(info);
 	info->xmit_count = 0;
 	restore_flags(flags);
-	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup) (tty);
+	tty_wakeup(tty);
 }
 
 static void
@@ -1867,8 +1858,7 @@ isdn_tty_close(struct tty_struct *tty, s
 	isdn_tty_shutdown(info);
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	tty_ldisc_flush(tty);
 	info->tty = 0;
 	info->ncarrier = 0;
 	tty->closing = 0;
@@ -2791,8 +2781,7 @@ isdn_tty_modem_result(int code, modem_in
 			restore_flags(flags);
 			return;
 		}
-		if (info->tty->ldisc.flush_buffer)
-			info->tty->ldisc.flush_buffer(info->tty);
+		tty_ldisc_flush(info->tty);
 		if ((info->flags & ISDN_ASYNC_CHECK_CD) &&
 		    (!((info->flags & ISDN_ASYNC_CALLOUT_ACTIVE) &&
 		       (info->flags & ISDN_ASYNC_CALLOUT_NOHUP)))) {
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/macintosh/macserial.c linux-2.4.29-pre3/drivers/macintosh/macserial.c
--- linux-2.4.28/drivers/macintosh/macserial.c	2002-08-03 00:39:44.000000000 +0000
+++ linux-2.4.29-pre3/drivers/macintosh/macserial.c	2004-12-22 16:06:34.093115000 +0000
@@ -735,12 +735,8 @@ static void do_softint(void *private_)
 	if (!tty)
 		return;
 
-	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup)(tty);
-		wake_up_interruptible(&tty->write_wait);
-	}
+	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) 
+		tty_wakeup(tty);
 }
 
 static int startup(struct mac_serial * info)
@@ -1595,10 +1591,7 @@ static void rs_flush_buffer(struct tty_s
 	save_flags(flags); cli();
 	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
 	restore_flags(flags);
-	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
+	tty_wakeup(tty);
 }
 
 /*
@@ -2029,8 +2022,7 @@ static void rs_close(struct tty_struct *
 
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	tty_ldisc_flush(tty);
 	tty->closing = 0;
 	info->event = 0;
 	info->tty = 0;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/net/3c505.c linux-2.4.29-pre3/drivers/net/3c505.c
--- linux-2.4.28/drivers/net/3c505.c	2003-11-28 18:26:20.000000000 +0000
+++ linux-2.4.29-pre3/drivers/net/3c505.c	2004-12-22 16:07:53.999967312 +0000
@@ -32,7 +32,7 @@
  *              Linux 1.3.0 changes by
  *                      Alan Cox <Alan.Cox@linux.org>
  *              More debugging, DMA support, currently maintained by
- *                      Philip Blundell <Philip.Blundell@pobox.com>
+ *                      Philip Blundell <philb@gnu.org>
  *              Multicard/soft configurable dma channel/rev 2 hardware support
  *                      by Christopher Collins <ccollins@pcug.org.au>
  *		Ethtool support (jgarzik), 11/17/2001
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/net/3c59x.c linux-2.4.29-pre3/drivers/net/3c59x.c
--- linux-2.4.28/drivers/net/3c59x.c	2003-11-28 18:26:20.000000000 +0000
+++ linux-2.4.29-pre3/drivers/net/3c59x.c	2004-12-22 16:05:31.143684768 +0000
@@ -166,12 +166,19 @@
     - Rename wait_for_completion() to issue_and_wait() to avoid completion.h
       clash.
 
-    LK1.1.18ac 01Jul02 akpm
-     - Fix for undocumented transceiver power-up bit on some 3c566B's
-       (Donald Becker, Rahul Karnik)
- 
+   LK1.1.17 18Dec01 akpm
+    - PCI ID 9805 is a Python-T, not a dual-port Cyclone.  Apparently.
+      And it has NWAY.
+    - Mask our advertised modes (vp->advertising) with our capabilities
+	  (MII reg5) when deciding which duplex mode to use.
+    - Add `global_options' as default for options[].  Ditto global_enable_wol,
+      global_full_duplex.
+
+   LK1.1.18 01Jul02 akpm
+    - Fix for undocumented transceiver power-up bit on some 3c566B's
+      (Donald Becker, Rahul Karnik)
 
-    - See http://www.uow.edu.au/~andrewm/linux/#3c59x-2.3 for more details.
+    - See http://www.zip.com.au/~akpm/linux/#3c59x-2.3 for more details.
     - Also see Documentation/networking/vortex.txt
 */
 
@@ -186,7 +193,7 @@
 
 
 #define DRV_NAME	"3c59x"
-#define DRV_VERSION	"LK1.1.18-ac"
+#define DRV_VERSION	"LK1.1.18"
 #define DRV_RELDATE	"1 July 2002"
 
 
@@ -201,11 +208,11 @@
 /* Set the copy breakpoint for the copy-only-tiny-frames scheme.
    Setting to > 1512 effectively disables this feature. */
 #ifndef __arm__
-static const int rx_copybreak = 200;
+static int rx_copybreak = 200;
 #else
 /* ARM systems perform better by disregarding the bus-master
    transfer capability of these cards. -- rmk */
-static const int rx_copybreak = 1513;
+static int rx_copybreak = 1513;
 #endif
 /* Allow setting MTU to a larger size, bypassing the normal ethernet setup. */
 static const int mtu = 1500;
@@ -228,16 +235,9 @@ static int vortex_debug = VORTEX_DEBUG;
 static int vortex_debug = 1;
 #endif
 
-#ifndef __OPTIMIZE__
-#error You must compile this file with the correct options!
-#error See the last lines of the source file.
-#error You must compile this driver with "-O".
-#endif
-
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/string.h>
 #include <linux/timer.h>
 #include <linux/errno.h>
@@ -246,6 +246,7 @@ static int vortex_debug = 1;
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
+#include <linux/if.h>
 #include <linux/mii.h>
 #include <linux/init.h>
 #include <linux/netdevice.h>
@@ -275,10 +276,13 @@ MODULE_DESCRIPTION("3Com 3c59x/3c9xx eth
 MODULE_LICENSE("GPL");
 
 MODULE_PARM(debug, "i");
+MODULE_PARM(global_options, "i");
 MODULE_PARM(options, "1-" __MODULE_STRING(8) "i");
+MODULE_PARM(global_full_duplex, "i");
 MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i");
 MODULE_PARM(hw_checksums, "1-" __MODULE_STRING(8) "i");
 MODULE_PARM(flow_ctrl, "1-" __MODULE_STRING(8) "i");
+MODULE_PARM(global_enable_wol, "i");
 MODULE_PARM(enable_wol, "1-" __MODULE_STRING(8) "i");
 MODULE_PARM(rx_copybreak, "i");
 MODULE_PARM(max_interrupt_work, "i");
@@ -288,10 +292,13 @@ MODULE_PARM(compaq_device_id, "i");
 MODULE_PARM(watchdog, "i");
 MODULE_PARM_DESC(debug, "3c59x debug level (0-6)");
 MODULE_PARM_DESC(options, "3c59x: Bits 0-3: media type, bit 4: bus mastering, bit 9: full duplex");
+MODULE_PARM_DESC(global_options, "3c59x: same as options, but applies to all NICs if options is unset");
 MODULE_PARM_DESC(full_duplex, "3c59x full duplex setting(s) (1)");
+MODULE_PARM_DESC(global_full_duplex, "3c59x: same as full_duplex, but applies to all NICs if options is unset");
 MODULE_PARM_DESC(hw_checksums, "3c59x Hardware checksum checking by adapter(s) (0-1)");
 MODULE_PARM_DESC(flow_ctrl, "3c59x 802.3x flow control usage (PAUSE only) (0-1)");
 MODULE_PARM_DESC(enable_wol, "3c59x: Turn on Wake-on-LAN for adapter(s) (0-1)");
+MODULE_PARM_DESC(global_enable_wol, "3c59x: same as enable_wol, but applies to all NICs if options is unset");
 MODULE_PARM_DESC(rx_copybreak, "3c59x copy breakpoint for copy-only-tiny-frames");
 MODULE_PARM_DESC(max_interrupt_work, "3c59x maximum events handled per interrupt");
 MODULE_PARM_DESC(compaq_ioaddr, "3c59x PCI I/O base address (Compaq BIOS problem workaround)");
@@ -405,7 +412,8 @@ enum {	IS_VORTEX=1, IS_BOOMERANG=2, IS_C
 	EEPROM_8BIT=0x10,	/* AKPM: Uses 0x230 as the base bitmaps for EEPROM reads */
 	HAS_PWR_CTRL=0x20, HAS_MII=0x40, HAS_NWAY=0x80, HAS_CB_FNS=0x100,
 	INVERT_MII_PWR=0x200, INVERT_LED_PWR=0x400, MAX_COLLISION_RESET=0x800,
-	EEPROM_OFFSET=0x1000, HAS_HWCKSM=0x2000, WNO_XCVR_PWR=0x4000 };
+	EEPROM_OFFSET=0x1000, HAS_HWCKSM=0x2000, WNO_XCVR_PWR=0x4000,
+	EXTRA_PREAMBLE=0x8000, };
 
 enum vortex_chips {
 	CH_3C590 = 0,
@@ -429,6 +437,7 @@ enum vortex_chips {
 	CH_3C905B_2,
 	CH_3C905B_FX,
 	CH_3C905C,
+	CH_3C9202,
 	CH_3C980,
 	CH_3C9805,
 
@@ -484,7 +493,7 @@ static struct vortex_chip_info {
 	{"3c900 Boomerang 10Mbps Combo",
 	 PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG, 64, },
 	{"3c900 Cyclone 10Mbps TPO",						/* AKPM: from Don's 0.99M */
-	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
+	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
 	{"3c900 Cyclone 10Mbps Combo",
 	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
 
@@ -497,19 +506,21 @@ static struct vortex_chip_info {
 	{"3c905 Boomerang 100baseT4",
 	 PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII, 64, },
 	{"3c905B Cyclone 100baseTx",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
+	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
 
 	{"3c905B Cyclone 10/100/BNC",
 	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
 	{"3c905B-FX Cyclone 100baseFx",
 	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
 	{"3c905C Tornado",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, },
+	PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
+	{"3c920B-EMB-WNM (ATI Radeon 9100 IGP)",
+	 PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_MII|HAS_HWCKSM, 128, },
 	{"3c980 Cyclone",
 	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
+
 	{"3c980C Python-T",
 	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
-
 	{"3cSOHO100-TX Hurricane",
 	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
 	{"3c555 Laptop Hurricane",
@@ -520,9 +531,9 @@ static struct vortex_chip_info {
 	{"3c556B Laptop Hurricane",
 	 PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|EEPROM_OFFSET|HAS_CB_FNS|INVERT_MII_PWR|
 	                                WNO_XCVR_PWR|HAS_HWCKSM, 128, },
+
 	{"3c575 [Megahertz] 10/100 LAN 	CardBus",
 	PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, },
-
 	{"3c575 Boomerang CardBus",
 	 PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, },
 	{"3CCFE575BT Cyclone CardBus",
@@ -534,10 +545,10 @@ static struct vortex_chip_info {
 	{"3CCFE656 Cyclone CardBus",
 	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR|
 									INVERT_LED_PWR|HAS_HWCKSM, 128, },
+
 	{"3CCFEM656B Cyclone+Winmodem CardBus",
 	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR|
 									INVERT_LED_PWR|HAS_HWCKSM, 128, },
-
 	{"3CXFEM656C Tornado+Winmodem CardBus",			/* From pcmcia-cs-3.1.5 */
 	 PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR|
 									MAX_COLLISION_RESET|HAS_HWCKSM, 128, },
@@ -547,19 +558,19 @@ static struct vortex_chip_info {
 	 PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, },
 	{"3c982 Hydra Dual Port A",
 	 PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, },
+
 	{"3c982 Hydra Dual Port B",
 	 PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, },
-
 	{"3c905B-T4",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
+	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
 	{"3c920B-EMB-WNM Tornado",
 	 PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, },
 
-	{0,}, /* 0 terminated list. */
+	{NULL,}, /* NULL terminated list. */
 };
 
 
-static struct pci_device_id vortex_pci_tbl[] __devinitdata = {
+static struct pci_device_id vortex_pci_tbl[] = {
 	{ 0x10B7, 0x5900, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C590 },
 	{ 0x10B7, 0x5920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C592 },
 	{ 0x10B7, 0x5970, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C597 },
@@ -581,6 +592,7 @@ static struct pci_device_id vortex_pci_t
 	{ 0x10B7, 0x9058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905B_2 },
 	{ 0x10B7, 0x905A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905B_FX },
 	{ 0x10B7, 0x9200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905C },
+	{ 0x10B7, 0x9202, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C9202 },
 	{ 0x10B7, 0x9800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C980 },
 	{ 0x10B7, 0x9805, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C9805 },
 
@@ -681,7 +693,7 @@ enum Window2 {			/* Window 2. */
 	Wn2_ResetOptions=12,
 };
 enum Window3 {			/* Window 3: MAC/config bits. */
-	Wn3_Config=0, Wn3_MAC_Ctrl=6, Wn3_Options=8,
+	Wn3_Config=0, Wn3_MaxPktSize=4, Wn3_MAC_Ctrl=6, Wn3_Options=8,
 };
 
 #define BFEXT(value, offset, bitcount)  \
@@ -709,7 +721,8 @@ enum Win4_Media_bits {
 	Media_LnkBeat = 0x0800,
 };
 enum Window7 {					/* Window 7: Bus Master control. */
-	Wn7_MasterAddr = 0, Wn7_MasterLen = 6, Wn7_MasterStatus = 12,
+	Wn7_MasterAddr = 0, Wn7_VlanEtherType=4, Wn7_MasterLen = 6,
+	Wn7_MasterStatus = 12,
 };
 /* Boomerang bus master control registers. */
 enum MasterCtrl {
@@ -806,7 +819,8 @@ struct vortex_private {
 		pm_state_valid:1,				/* power_state[] has sane contents */
 		open:1,
 		medialock:1,
-		must_free_region:1;				/* Flag: if zero, Cardbus owns the I/O region */
+		must_free_region:1,				/* Flag: if zero, Cardbus owns the I/O region */
+		large_frames:1;			/* accept large frames */
 	int drv_flags;
 	u16 status_enable;
 	u16 intr_enable;
@@ -822,6 +836,12 @@ struct vortex_private {
 	u32 power_state[16];
 };
 
+#ifdef CONFIG_PCI
+#define VORTEX_PCI(dev) ((dev)->pdev)
+#else
+#define VORTEX_PCI(dev) NULL
+#endif
+
 /* The action to take with a media selection timer tick.
    Note that we deviate from the 3Com order by checking 10base2 before AUI.
  */
@@ -853,7 +873,7 @@ static struct media_table {
 static int vortex_probe1(struct pci_dev *pdev, long ioaddr, int irq,
 				   int chip_idx, int card_idx);
 static void vortex_up(struct net_device *dev);
-static void vortex_down(struct net_device *dev);
+static void vortex_down(struct net_device *dev, int final);
 static int vortex_open(struct net_device *dev);
 static void mdio_sync(long ioaddr, int bits);
 static int mdio_read(struct net_device *dev, int phy_id, int location);
@@ -864,17 +884,21 @@ static int vortex_start_xmit(struct sk_b
 static int boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static int vortex_rx(struct net_device *dev);
 static int boomerang_rx(struct net_device *dev);
-static void vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static void boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static int vortex_close(struct net_device *dev);
 static void dump_tx_ring(struct net_device *dev);
 static void update_stats(long ioaddr, struct net_device *dev);
 static struct net_device_stats *vortex_get_stats(struct net_device *dev);
 static void set_rx_mode(struct net_device *dev);
+#ifdef CONFIG_PCI
 static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+#endif
 static void vortex_tx_timeout(struct net_device *dev);
 static void acpi_set_WOL(struct net_device *dev);
 static struct ethtool_ops vortex_ethtool_ops;
+static void set_8021q_mode(struct net_device *dev, int enable);
+
 
 /* This driver uses 'options' to pass the media type, full-duplex flag, etc. */
 /* Option count limit only -- unlimited interfaces are supported. */
@@ -884,6 +908,9 @@ static int full_duplex[MAX_UNITS] = {-1,
 static int hw_checksums[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
 static int flow_ctrl[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
 static int enable_wol[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
+static int global_options = -1;
+static int global_full_duplex = -1;
+static int global_enable_wol = -1;
 
 /* #define dev_alloc_skb dev_alloc_skb_debug */
 
@@ -895,6 +922,18 @@ static int compaq_ioaddr, compaq_irq, co
 
 static int vortex_cards_found;
 
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void poll_vortex(struct net_device *dev)
+{
+	struct vortex_private *vp = (struct vortex_private *)dev->priv;
+	unsigned long flags;
+	local_save_flags(flags);
+	local_irq_disable();
+	(vp->full_bus_master_rx ? boomerang_interrupt:vortex_interrupt)(dev->irq,dev,NULL);
+	local_irq_restore(flags);
+} 
+#endif
+
 #ifdef CONFIG_PM
 
 static int vortex_suspend (struct pci_dev *pdev, u32 state)
@@ -904,7 +943,7 @@ static int vortex_suspend (struct pci_de
 	if (dev && dev->priv) {
 		if (netif_running(dev)) {
 			netif_device_detach(dev);
-			vortex_down(dev);
+			vortex_down(dev, 1);
 		}
 	}
 	return 0;
@@ -1006,9 +1045,9 @@ static int __devinit vortex_probe1(struc
 	int i, step;
 	struct net_device *dev;
 	static int printed_version;
-	int retval;
+	int retval, print_info;
 	struct vortex_chip_info * const vci = &vortex_info_tbl[chip_idx];
-	char *print_name;
+	char *print_name = "3c59x";
 
 	if (!printed_version) {
 		printk (version);
@@ -1024,7 +1063,10 @@ static int __devinit vortex_probe1(struc
 		goto out;
 	}
 	SET_MODULE_OWNER(dev);
-	vp = dev->priv;
+	SET_NETDEV_DEV(dev, gendev);
+	vp = netdev_priv(dev);
+
+	option = global_options;
 
 	/* The lower four bits are the media type. */
 	if (dev->mem_start) {
@@ -1034,10 +1076,10 @@ static int __devinit vortex_probe1(struc
 		 */
 		option = dev->mem_start;
 	}
-	else if (card_idx < MAX_UNITS)
-		option = options[card_idx];
-	else
-		option = -1;
+	else if (card_idx < MAX_UNITS) {
+		if (options[card_idx] >= 0)
+			option = options[card_idx];
+	}
 
 	if (option > 0) {
 		if (option & 0x8000)
@@ -1048,7 +1090,10 @@ static int __devinit vortex_probe1(struc
 			vp->enable_wol = 1;
 	}
 
-	printk (KERN_INFO "See Documentation/networking/vortex.txt\n");
+	print_info = (vortex_debug > 1);
+	if (print_info)
+		printk (KERN_INFO "See Documentation/networking/vortex.txt\n");
+
 	printk(KERN_INFO "%s: 3Com %s %s at 0x%lx. Vers " DRV_VERSION "\n",
 	       print_name,
 	       pdev ? "PCI" : "EISA",
@@ -1058,6 +1103,7 @@ static int __devinit vortex_probe1(struc
 	dev->base_addr = ioaddr;
 	dev->irq = irq;
 	dev->mtu = mtu;
+	vp->large_frames = mtu > 1500;
 	vp->drv_flags = vci->drv_flags;
 	vp->has_nway = (vci->drv_flags & HAS_NWAY) ? 1 : 0;
 	vp->io_size = vci->io_size;
@@ -1127,6 +1173,11 @@ static int __devinit vortex_probe1(struc
 		vp->bus_master = (option & 16) ? 1 : 0;
 	}
 
+	if (global_full_duplex > 0)
+		vp->full_duplex = 1;
+	if (global_enable_wol > 0)
+		vp->enable_wol = 1;
+
 	if (card_idx < MAX_UNITS) {
 		if (full_duplex[card_idx] > 0)
 			vp->full_duplex = 1;
@@ -1174,16 +1225,20 @@ static int __devinit vortex_probe1(struc
 		printk(" ***INVALID CHECKSUM %4.4x*** ", checksum);
 	for (i = 0; i < 3; i++)
 		((u16 *)dev->dev_addr)[i] = htons(eeprom[i + 10]);
-	for (i = 0; i < 6; i++)
-		printk("%c%2.2x", i ? ':' : ' ', dev->dev_addr[i]);
+	if (print_info) {
+		for (i = 0; i < 6; i++)
+			printk("%c%2.2x", i ? ':' : ' ', dev->dev_addr[i]);
+	}
 	EL3WINDOW(2);
 	for (i = 0; i < 6; i++)
 		outb(dev->dev_addr[i], ioaddr + i);
 
 #ifdef __sparc__
-	printk(", IRQ %s\n", __irq_itoa(dev->irq));
+	if (print_info)
+		printk(", IRQ %s\n", __irq_itoa(dev->irq));
 #else
-	printk(", IRQ %d\n", dev->irq);
+	if (print_info)
+		printk(", IRQ %d\n", dev->irq);
 	/* Tell them about an invalid IRQ. */
 	if (dev->irq <= 0 || dev->irq >= NR_IRQS)
 		printk(KERN_WARNING " *** Warning: IRQ %d is unlikely to work! ***\n",
@@ -1192,9 +1247,12 @@ static int __devinit vortex_probe1(struc
 
 	EL3WINDOW(4);
 	step = (inb(ioaddr + Wn4_NetDiag) & 0x1e) >> 1;
-	printk(KERN_INFO "  product code %02x%02x rev %02x.%d date %02d-"
-		"%02d-%02d\n", eeprom[6]&0xff, eeprom[6]>>8, eeprom[0x14],
-		step, (eeprom[4]>>5) & 15, eeprom[4] & 31, eeprom[4]>>9);
+	if (print_info) {
+		printk(KERN_INFO "  product code %02x%02x rev %02x.%d date %02d-"
+			"%02d-%02d\n", eeprom[6]&0xff, eeprom[6]>>8, eeprom[0x14],
+			step, (eeprom[4]>>5) & 15, eeprom[4] & 31, eeprom[4]>>9);
+	}
+
 
 	if (pdev && vci->drv_flags & HAS_CB_FNS) {
 		unsigned long fn_st_addr;			/* Cardbus function status space */
@@ -1207,8 +1265,10 @@ static int __devinit vortex_probe1(struc
 			if (!vp->cb_fn_base)
 				goto free_ring;
 		}
-		printk(KERN_INFO "%s: CardBus functions mapped %8.8lx->%p\n",
-			print_name, fn_st_addr, vp->cb_fn_base);
+		if (print_info) {
+			printk(KERN_INFO "%s: CardBus functions mapped %8.8lx->%p\n",
+				print_name, fn_st_addr, vp->cb_fn_base);
+		}
 		EL3WINDOW(2);
 
 		n = inw(ioaddr + Wn2_ResetOptions) & ~0x4010;
@@ -1230,7 +1290,8 @@ static int __devinit vortex_probe1(struc
 
 	if (vp->info1 & 0x8000) {
 		vp->full_duplex = 1;
-		printk(KERN_INFO "Full duplex capable\n");
+		if (print_info)
+			printk(KERN_INFO "Full duplex capable\n");
 	}
 
 	{
@@ -1241,16 +1302,17 @@ static int __devinit vortex_probe1(struc
 		if ((vp->available_media & 0xff) == 0)		/* Broken 3c916 */
 			vp->available_media = 0x40;
 		config = inl(ioaddr + Wn3_Config);
-		printk(KERN_DEBUG "  Internal config register is %4.4x, "
-				"transceivers %#x.\n", config,
-				inw(ioaddr + Wn3_Options));
-		printk(KERN_INFO "  %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
-			   8 << RAM_SIZE(config),
-			   RAM_WIDTH(config) ? "word" : "byte",
-			   ram_split[RAM_SPLIT(config)],
-			   AUTOSELECT(config) ? "autoselect/" : "",
-			   XCVR(config) > XCVR_ExtMII ? "<invalid transceiver>" :
-			   media_tbl[XCVR(config)].name);
+		if (print_info) {
+			printk(KERN_DEBUG "  Internal config register is %4.4x, "
+				   "transceivers %#x.\n", config, inw(ioaddr + Wn3_Options));
+			printk(KERN_INFO "  %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
+				   8 << RAM_SIZE(config),
+				   RAM_WIDTH(config) ? "word" : "byte",
+				   ram_split[RAM_SPLIT(config)],
+				   AUTOSELECT(config) ? "autoselect/" : "",
+				   XCVR(config) > XCVR_ExtMII ? "<invalid transceiver>" :
+				   media_tbl[XCVR(config)].name);
+		}
 		vp->default_media = XCVR(config);
 		if (vp->default_media == XCVR_NWAY)
 			vp->has_nway = 1;
@@ -1265,11 +1327,14 @@ static int __devinit vortex_probe1(struc
 	} else
 		dev->if_port = vp->default_media;
 
-	if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) {
+	if ((vp->available_media & 0x40) || (vci->drv_flags & HAS_NWAY) ||
+		dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) {
 		int phy, phy_idx = 0;
 		EL3WINDOW(4);
 		mii_preamble_required++;
-		mii_preamble_required++;
+		if (vp->drv_flags & EXTRA_PREAMBLE)
+			mii_preamble_required++;
+		mdio_sync(ioaddr, 32);
 		mdio_read(dev, 24, 1);
 		for (phy = 0; phy < 32 && phy_idx < 1; phy++) {
 			int mii_status, phyx;
@@ -1287,9 +1352,10 @@ static int __devinit vortex_probe1(struc
 			mii_status = mdio_read(dev, phyx, 1);
 			if (mii_status  &&  mii_status != 0xffff) {
 				vp->phys[phy_idx++] = phyx;
-				printk(KERN_INFO "  MII transceiver found at "
-					"address %d, status %4x.\n",
-					phyx, mii_status);
+				if (print_info) {
+					printk(KERN_INFO "  MII transceiver found at address %d,"
+						" status %4x.\n", phyx, mii_status);
+				}
 				if ((mii_status & 0x0040) == 0)
 					mii_preamble_required++;
 			}
@@ -1310,9 +1376,10 @@ static int __devinit vortex_probe1(struc
 
 	if (vp->capabilities & CapBusMaster) {
 		vp->full_bus_master_tx = 1;
-		printk(KERN_INFO "  Enabling bus-master transmits and %s "
-				"receives.\n",
+		if (print_info) {
+			printk(KERN_INFO "  Enabling bus-master transmits and %s receives.\n",
 			(vp->info2 & 1) ? "early" : "whole-frame" );
+		}
 		vp->full_bus_master_rx = (vp->info2 & 1) ? 1 : 2;
 		vp->bus_master = 0;		/* AKPM: vortex only */
 	}
@@ -1331,21 +1398,28 @@ static int __devinit vortex_probe1(struc
 		dev->hard_start_xmit = vortex_start_xmit;
 	}
 
-	printk(KERN_INFO "%s: scatter/gather %sabled. h/w checksums %sabled\n",
-			print_name,
-			(dev->features & NETIF_F_SG) ? "en":"dis",
-			(dev->features & NETIF_F_IP_CSUM) ? "en":"dis");
+	if (print_info) {
+		printk(KERN_INFO "%s: scatter/gather %sabled. h/w checksums %sabled\n",
+				print_name,
+				(dev->features & NETIF_F_SG) ? "en":"dis",
+				(dev->features & NETIF_F_IP_CSUM) ? "en":"dis");
+	}
 
 	dev->stop = vortex_close;
 	dev->get_stats = vortex_get_stats;
+#ifdef CONFIG_PCI
 	dev->do_ioctl = vortex_ioctl;
+#endif
 	dev->ethtool_ops = &vortex_ethtool_ops;
 	dev->set_multicast_list = set_rx_mode;
 	dev->tx_timeout = vortex_tx_timeout;
 	dev->watchdog_timeo = (watchdog * HZ) / 1000;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	dev->poll_controller = poll_vortex; 
+#endif
 	if (pdev && vp->enable_wol) {
 		vp->pm_state_valid = 1;
- 		pci_save_state(vp->pdev, vp->power_state);
+ 		pci_save_state(VORTEX_PCI(vp), vp->power_state);
  		acpi_set_WOL(dev);
 	}
 	retval = register_netdev(dev);
@@ -1361,7 +1435,7 @@ free_ring:
 free_region:
 	if (vp->must_free_region)
 		release_region(ioaddr, vci->io_size);
-	kfree (dev);
+	free_netdev(dev);
 	printk(KERN_ERR PFX "vortex_probe1 fails.  Returns %d\n", retval);
 out:
 	return retval;
@@ -1396,13 +1470,13 @@ static void
 vortex_up(struct net_device *dev)
 {
 	long ioaddr = dev->base_addr;
-	struct vortex_private *vp = (struct vortex_private *)dev->priv;
+	struct vortex_private *vp = netdev_priv(dev);
 	unsigned int config;
 	int i;
 
-	if (vp->pdev && vp->enable_wol) {
-		pci_set_power_state(vp->pdev, 0);	/* Go active */
-		pci_restore_state(vp->pdev, vp->power_state);
+	if (VORTEX_PCI(vp) && vp->enable_wol) {
+		pci_set_power_state(VORTEX_PCI(vp), 0);	/* Go active */
+		pci_restore_state(VORTEX_PCI(vp), vp->power_state);
 	}
 
 	/* Before initializing select the active media port. */
@@ -1465,9 +1539,10 @@ vortex_up(struct net_device *dev)
 		if (mii_reg5 == 0xffff  ||  mii_reg5 == 0x0000) {
 			netif_carrier_off(dev); /* No MII device or no link partner report */
 		} else {
+			mii_reg5 &= vp->advertising;
 			if ((mii_reg5 & 0x0100) != 0	/* 100baseTx-FD */
 				 || (mii_reg5 & 0x00C0) == 0x0040) /* 10T-FD, but not 100-HD */
-				vp->full_duplex = 1;
+			vp->full_duplex = 1;
 			netif_carrier_on(dev);
 		}
 		vp->partner_flow_ctrl = ((mii_reg5 & 0x0400) != 0);
@@ -1482,7 +1557,7 @@ vortex_up(struct net_device *dev)
 
 	/* Set the full-duplex bit. */
 	outw(	((vp->info1 & 0x8000) || vp->full_duplex ? 0x20 : 0) |
-		 	(dev->mtu > 1500 ? 0x40 : 0) |
+		 	(vp->large_frames ? 0x40 : 0) |
 			((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ? 0x100 : 0),
 			ioaddr + Wn3_MAC_Ctrl);
 
@@ -1561,11 +1636,13 @@ vortex_up(struct net_device *dev)
 		for (i = 0; i < RX_RING_SIZE; i++)	/* AKPM: this is done in vortex_open, too */
 			vp->rx_ring[i].status = 0;
 		for (i = 0; i < TX_RING_SIZE; i++)
-			vp->tx_skbuff[i] = 0;
+			vp->tx_skbuff[i] = NULL;
 		outl(0, ioaddr + DownListPtr);
 	}
 	/* Set receiver mode: presumably accept b-case and phys addr only. */
 	set_rx_mode(dev);
+	/* enable 802.1q tagged frames */
+	set_8021q_mode(dev, 1);
 	outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
 
 //	issue_and_wait(dev, SetTxStart|0x07ff);
@@ -1593,7 +1670,7 @@ vortex_up(struct net_device *dev)
 static int
 vortex_open(struct net_device *dev)
 {
-	struct vortex_private *vp = (struct vortex_private *)dev->priv;
+	struct vortex_private *vp = netdev_priv(dev);
 	int i;
 	int retval;
 
@@ -1618,7 +1695,7 @@ vortex_open(struct net_device *dev)
 				break;			/* Bad news!  */
 			skb->dev = dev;			/* Mark as being used by this device. */
 			skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
-			vp->rx_ring[i].addr = cpu_to_le32(pci_map_single(vp->pdev, skb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
+			vp->rx_ring[i].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
 		}
 		if (i != RX_RING_SIZE) {
 			int j;
@@ -1626,7 +1703,7 @@ vortex_open(struct net_device *dev)
 			for (j = 0; j < i; j++) {
 				if (vp->rx_skbuff[j]) {
 					dev_kfree_skb(vp->rx_skbuff[j]);
-					vp->rx_skbuff[j] = 0;
+					vp->rx_skbuff[j] = NULL;
 				}
 			}
 			retval = -ENOMEM;
@@ -1651,7 +1728,7 @@ static void
 vortex_timer(unsigned long data)
 {
 	struct net_device *dev = (struct net_device *)data;
-	struct vortex_private *vp = (struct vortex_private *)dev->priv;
+	struct vortex_private *vp = netdev_priv(dev);
 	long ioaddr = dev->base_addr;
 	int next_tick = 60*HZ;
 	int ok = 0;
@@ -1695,8 +1772,10 @@ vortex_timer(unsigned long data)
 			if (mii_status & BMSR_LSTATUS) {
 				int mii_reg5 = mdio_read(dev, vp->phys[0], 5);
 				if (! vp->force_fd  &&  mii_reg5 != 0xffff) {
-					int duplex = (mii_reg5&0x0100) ||
-						(mii_reg5 & 0x01C0) == 0x0040;
+					int duplex;
+
+					mii_reg5 &= vp->advertising;
+					duplex = (mii_reg5&0x0100) || (mii_reg5 & 0x01C0) == 0x0040;
 					if (vp->full_duplex != duplex) {
 						vp->full_duplex = duplex;
 						printk(KERN_INFO "%s: Setting %s-duplex based on MII "
@@ -1706,7 +1785,7 @@ vortex_timer(unsigned long data)
 						/* Set the full-duplex bit. */
 						EL3WINDOW(3);
 						outw(	(vp->full_duplex ? 0x20 : 0) |
-								(dev->mtu > 1500 ? 0x40 : 0) |
+								(vp->large_frames ? 0x40 : 0) |
 								((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ? 0x100 : 0),
 								ioaddr + Wn3_MAC_Ctrl);
 						if (vortex_debug > 1)
@@ -1775,16 +1854,18 @@ leave_media_alone:
 
 static void vortex_tx_timeout(struct net_device *dev)
 {
-	struct vortex_private *vp = (struct vortex_private *)dev->priv;
+	struct vortex_private *vp = netdev_priv(dev);
 	long ioaddr = dev->base_addr;
 
 	printk(KERN_ERR "%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
 		   dev->name, inb(ioaddr + TxStatus),
 		   inw(ioaddr + EL3_STATUS));
 	EL3WINDOW(4);
-	printk(KERN_ERR "  diagnostics: net %04x media %04x dma %8.8x.\n",
-		   inw(ioaddr + Wn4_NetDiag), inw(ioaddr + Wn4_Media),
-		   inl(ioaddr + PktStatus));
+	printk(KERN_ERR "  diagnostics: net %04x media %04x dma %08x fifo %04x\n",
+			inw(ioaddr + Wn4_NetDiag),
+			inw(ioaddr + Wn4_Media),
+			inl(ioaddr + PktStatus),
+			inw(ioaddr + Wn4_FIFODiag));
 	/* Slight code bloat to be user friendly. */
 	if ((inb(ioaddr + TxStatus) & 0x88) == 0x88)
 		printk(KERN_ERR "%s: Transmitter encountered 16 collisions --"
@@ -1800,9 +1881,9 @@ static void vortex_tx_timeout(struct net
 			unsigned long flags;
 			local_irq_save(flags);
 			if (vp->full_bus_master_tx)
-				boomerang_interrupt(dev->irq, dev, 0);
+				boomerang_interrupt(dev->irq, dev, NULL);
 			else
-				vortex_interrupt(dev->irq, dev, 0);
+				vortex_interrupt(dev->irq, dev, NULL);
 			local_irq_restore(flags);
 		}
 	}
@@ -1843,7 +1924,7 @@ static void vortex_tx_timeout(struct net
 static void
 vortex_error(struct net_device *dev, int status)
 {
-	struct vortex_private *vp = (struct vortex_private *)dev->priv;
+	struct vortex_private *vp = netdev_priv(dev);
 	long ioaddr = dev->base_addr;
 	int do_tx_reset = 0, reset_mask = 0;
 	unsigned char tx_status = 0;
@@ -1919,7 +2000,8 @@ vortex_error(struct net_device *dev, int
 				printk(KERN_ERR "%s: PCI bus error, bus status %8.8x\n", dev->name, bus_status);
 
 			/* In this case, blow the card away */
-			vortex_down(dev);
+			/* Must not enter D3 or we can't legally issue the reset! */
+			vortex_down(dev, 0);
 			issue_and_wait(dev, TotalReset | 0xff);
 			vortex_up(dev);		/* AKPM: bug.  vortex_up() assumes that the rx ring is full. It may not be. */
 		} else if (fifo_diag & 0x0400)
@@ -1929,6 +2011,8 @@ vortex_error(struct net_device *dev, int
 			issue_and_wait(dev, RxReset|0x07);
 			/* Set the Rx filter to the current state. */
 			set_rx_mode(dev);
+			/* enable 802.1q VLAN tagged frames */
+			set_8021q_mode(dev, 1);
 			outw(RxEnable, ioaddr + EL3_CMD); /* Re-enable the receiver. */
 			outw(AckIntr | HostError, ioaddr + EL3_CMD);
 		}
@@ -1945,7 +2029,7 @@ vortex_error(struct net_device *dev, int
 static int
 vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct vortex_private *vp = (struct vortex_private *)dev->priv;
+	struct vortex_private *vp = netdev_priv(dev);
 	long ioaddr = dev->base_addr;
 
 	/* Put out the doubleword header... */
@@ -1953,7 +2037,7 @@ vortex_start_xmit(struct sk_buff *skb, s
 	if (vp->bus_master) {
 		/* Set the bus-master controller to transfer the packet. */
 		int len = (skb->len + 3) & ~3;
-		outl(	vp->tx_skb_dma = pci_map_single(vp->pdev, skb->data, len, PCI_DMA_TODEVICE),
+		outl(	vp->tx_skb_dma = pci_map_single(VORTEX_PCI(vp), skb->data, len, PCI_DMA_TODEVICE),
 				ioaddr + Wn7_MasterAddr);
 		outw(len, ioaddr + Wn7_MasterLen);
 		vp->tx_skb = skb;
@@ -2000,7 +2084,7 @@ vortex_start_xmit(struct sk_buff *skb, s
 static int
 boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct vortex_private *vp = (struct vortex_private *)dev->priv;
+	struct vortex_private *vp = netdev_priv(dev);
 	long ioaddr = dev->base_addr;
 	/* Calculate the next Tx descriptor entry. */
 	int entry = vp->cur_tx % TX_RING_SIZE;
@@ -2029,16 +2113,16 @@ boomerang_start_xmit(struct sk_buff *skb
 	if (skb->ip_summed != CHECKSUM_HW)
 			vp->tx_ring[entry].status = cpu_to_le32(skb->len | TxIntrUploaded);
 	else
-			vp->tx_ring[entry].status = cpu_to_le32(skb->len | TxIntrUploaded | AddTCPChksum);
+			vp->tx_ring[entry].status = cpu_to_le32(skb->len | TxIntrUploaded | AddTCPChksum | AddUDPChksum);
 
 	if (!skb_shinfo(skb)->nr_frags) {
-		vp->tx_ring[entry].frag[0].addr = cpu_to_le32(pci_map_single(vp->pdev, skb->data,
+		vp->tx_ring[entry].frag[0].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data,
 										skb->len, PCI_DMA_TODEVICE));
 		vp->tx_ring[entry].frag[0].length = cpu_to_le32(skb->len | LAST_FRAG);
 	} else {
 		int i;
 
-		vp->tx_ring[entry].frag[0].addr = cpu_to_le32(pci_map_single(vp->pdev, skb->data,
+		vp->tx_ring[entry].frag[0].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data,
 										skb->len-skb->data_len, PCI_DMA_TODEVICE));
 		vp->tx_ring[entry].frag[0].length = cpu_to_le32(skb->len-skb->data_len);
 
@@ -2046,7 +2130,7 @@ boomerang_start_xmit(struct sk_buff *skb
 			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
 			vp->tx_ring[entry].frag[i+1].addr =
-					cpu_to_le32(pci_map_single(vp->pdev,
+					cpu_to_le32(pci_map_single(VORTEX_PCI(vp),
 											   (void*)page_address(frag->page) + frag->page_offset,
 											   frag->size, PCI_DMA_TODEVICE));
 
@@ -2057,7 +2141,7 @@ boomerang_start_xmit(struct sk_buff *skb
 		}
 	}
 #else
-	vp->tx_ring[entry].addr = cpu_to_le32(pci_map_single(vp->pdev, skb->data, skb->len, PCI_DMA_TODEVICE));
+	vp->tx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, skb->len, PCI_DMA_TODEVICE));
 	vp->tx_ring[entry].length = cpu_to_le32(skb->len | LAST_FRAG);
 	vp->tx_ring[entry].status = cpu_to_le32(skb->len | TxIntrUploaded);
 #endif
@@ -2096,14 +2180,16 @@ boomerang_start_xmit(struct sk_buff *skb
  * full_bus_master_tx == 0 && full_bus_master_rx == 0
  */
 
-static void vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t
+vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct net_device *dev = dev_id;
-	struct vortex_private *vp = (struct vortex_private *)dev->priv;
+	struct vortex_private *vp = netdev_priv(dev);
 	long ioaddr;
 	int status;
 	int work_done = max_interrupt_work;
-	
+	int handled = 0;
+
 	ioaddr = dev->base_addr;
 	spin_lock(&vp->lock);
 
@@ -2114,6 +2200,7 @@ static void vortex_interrupt(int irq, vo
 
 	if ((status & IntLatch) == 0)
 		goto handler_exit;		/* No interrupt: shared IRQs cause this */
+	handled = 1;
 
 	if (status & IntReq) {
 		status |= vp->deferred;
@@ -2145,7 +2232,7 @@ static void vortex_interrupt(int irq, vo
 		if (status & DMADone) {
 			if (inw(ioaddr + Wn7_MasterStatus) & 0x1000) {
 				outw(0x1000, ioaddr + Wn7_MasterStatus); /* Ack the event. */
-				pci_unmap_single(vp->pdev, vp->tx_skb_dma, (vp->tx_skb->len + 3) & ~3, PCI_DMA_TODEVICE);
+				pci_unmap_single(VORTEX_PCI(vp), vp->tx_skb_dma, (vp->tx_skb->len + 3) & ~3, PCI_DMA_TODEVICE);
 				dev_kfree_skb_irq(vp->tx_skb); /* Release the transferred buffer */
 				if (inw(ioaddr + TxFree) > 1536) {
 					/*
@@ -2190,6 +2277,7 @@ static void vortex_interrupt(int irq, vo
 			   dev->name, status);
 handler_exit:
 	spin_unlock(&vp->lock);
+	return IRQ_RETVAL(handled);
 }
 
 /*
@@ -2197,10 +2285,11 @@ handler_exit:
  * full_bus_master_tx == 1 && full_bus_master_rx == 1
  */
 
-static void boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t
+boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct net_device *dev = dev_id;
-	struct vortex_private *vp = (struct vortex_private *)dev->priv;
+	struct vortex_private *vp = netdev_priv(dev);
 	long ioaddr;
 	int status;
 	int work_done = max_interrupt_work;
@@ -2266,16 +2355,16 @@ static void boomerang_interrupt(int irq,
 #if DO_ZEROCOPY					
 					int i;
 					for (i=0; i<=skb_shinfo(skb)->nr_frags; i++)
-							pci_unmap_single(vp->pdev,
+							pci_unmap_single(VORTEX_PCI(vp),
 											 le32_to_cpu(vp->tx_ring[entry].frag[i].addr),
 											 le32_to_cpu(vp->tx_ring[entry].frag[i].length)&0xFFF,
 											 PCI_DMA_TODEVICE);
 #else
-					pci_unmap_single(vp->pdev,
+					pci_unmap_single(VORTEX_PCI(vp),
 						le32_to_cpu(vp->tx_ring[entry].addr), skb->len, PCI_DMA_TODEVICE);
 #endif
 					dev_kfree_skb_irq(skb);
-					vp->tx_skbuff[entry] = 0;
+					vp->tx_skbuff[entry] = NULL;
 				} else {
 					printk(KERN_DEBUG "boomerang_interrupt: no skb!\n");
 				}
@@ -2320,11 +2409,12 @@ static void boomerang_interrupt(int irq,
 			   dev->name, status);
 handler_exit:
 	spin_unlock(&vp->lock);
+	return IRQ_HANDLED;
 }
 
 static int vortex_rx(struct net_device *dev)
 {
-	struct vortex_private *vp = (struct vortex_private *)dev->priv;
+	struct vortex_private *vp = netdev_priv(dev);
 	long ioaddr = dev->base_addr;
 	int i;
 	short rx_status;
@@ -2358,14 +2448,14 @@ static int vortex_rx(struct net_device *
 				/* 'skb_put()' points to the start of sk_buff data area. */
 				if (vp->bus_master &&
 					! (inw(ioaddr + Wn7_MasterStatus) & 0x8000)) {
-					dma_addr_t dma = pci_map_single(vp->pdev, skb_put(skb, pkt_len),
+					dma_addr_t dma = pci_map_single(VORTEX_PCI(vp), skb_put(skb, pkt_len),
 									   pkt_len, PCI_DMA_FROMDEVICE);
 					outl(dma, ioaddr + Wn7_MasterAddr);
 					outw((skb->len + 3) & ~3, ioaddr + Wn7_MasterLen);
 					outw(StartDMAUp, ioaddr + EL3_CMD);
 					while (inw(ioaddr + Wn7_MasterStatus) & 0x8000)
 						;
-					pci_unmap_single(vp->pdev, dma, pkt_len, PCI_DMA_FROMDEVICE);
+					pci_unmap_single(VORTEX_PCI(vp), dma, pkt_len, PCI_DMA_FROMDEVICE);
 				} else {
 					insl(ioaddr + RX_FIFO, skb_put(skb, pkt_len),
 						 (pkt_len + 3) >> 2);
@@ -2394,7 +2484,7 @@ static int vortex_rx(struct net_device *
 static int
 boomerang_rx(struct net_device *dev)
 {
-	struct vortex_private *vp = (struct vortex_private *)dev->priv;
+	struct vortex_private *vp = netdev_priv(dev);
 	int entry = vp->cur_rx % RX_RING_SIZE;
 	long ioaddr = dev->base_addr;
 	int rx_status;
@@ -2431,18 +2521,19 @@ boomerang_rx(struct net_device *dev)
 			if (pkt_len < rx_copybreak && (skb = dev_alloc_skb(pkt_len + 2)) != 0) {
 				skb->dev = dev;
 				skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
-				pci_dma_sync_single(vp->pdev, dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
+				pci_dma_sync_single(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
 				/* 'skb_put()' points to the start of sk_buff data area. */
 				memcpy(skb_put(skb, pkt_len),
 					   vp->rx_skbuff[entry]->tail,
 					   pkt_len);
+				pci_dma_sync_single(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
 				vp->rx_copy++;
 			} else {
 				/* Pass up the skbuff already on the Rx ring. */
 				skb = vp->rx_skbuff[entry];
 				vp->rx_skbuff[entry] = NULL;
 				skb_put(skb, pkt_len);
-				pci_unmap_single(vp->pdev, dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
+				pci_unmap_single(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
 				vp->rx_nocopy++;
 			}
 			skb->protocol = eth_type_trans(skb, dev);
@@ -2479,7 +2570,7 @@ boomerang_rx(struct net_device *dev)
 			}
 			skb->dev = dev;			/* Mark as being used by this device. */
 			skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
-			vp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(vp->pdev, skb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
+			vp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
 			vp->rx_skbuff[entry] = skb;
 		}
 		vp->rx_ring[entry].status = 0;	/* Clear complete bit. */
@@ -2496,7 +2587,7 @@ static void
 rx_oom_timer(unsigned long arg)
 {
 	struct net_device *dev = (struct net_device *)arg;
-	struct vortex_private *vp = (struct vortex_private *)dev->priv;
+	struct vortex_private *vp = netdev_priv(dev);
 
 	spin_lock_irq(&vp->lock);
 	if ((vp->cur_rx - vp->dirty_rx) == RX_RING_SIZE)	/* This test is redundant, but makes me feel good */
@@ -2509,9 +2600,9 @@ rx_oom_timer(unsigned long arg)
 }
 
 static void
-vortex_down(struct net_device *dev)
+vortex_down(struct net_device *dev, int final_down)
 {
-	struct vortex_private *vp = (struct vortex_private *)dev->priv;
+	struct vortex_private *vp = netdev_priv(dev);
 	long ioaddr = dev->base_addr;
 
 	netif_stop_queue (dev);
@@ -2526,6 +2617,9 @@ vortex_down(struct net_device *dev)
 	outw(RxDisable, ioaddr + EL3_CMD);
 	outw(TxDisable, ioaddr + EL3_CMD);
 
+	/* Disable receiving 802.1q tagged frames */
+	set_8021q_mode(dev, 0);
+
 	if (dev->if_port == XCVR_10base2)
 		/* Turn off thinnet power.  Green! */
 		outw(StopCoax, ioaddr + EL3_CMD);
@@ -2538,8 +2632,8 @@ vortex_down(struct net_device *dev)
 	if (vp->full_bus_master_tx)
 		outl(0, ioaddr + DownListPtr);
 
-	if (vp->pdev && vp->enable_wol) {
-		pci_save_state(vp->pdev, vp->power_state);
+	if (final_down && VORTEX_PCI(vp) && vp->enable_wol) {
+		pci_save_state(VORTEX_PCI(vp), vp->power_state);
 		acpi_set_WOL(dev);
 	}
 }
@@ -2547,12 +2641,12 @@ vortex_down(struct net_device *dev)
 static int
 vortex_close(struct net_device *dev)
 {
-	struct vortex_private *vp = (struct vortex_private *)dev->priv;
+	struct vortex_private *vp = netdev_priv(dev);
 	long ioaddr = dev->base_addr;
 	int i;
 
 	if (netif_device_present(dev))
-		vortex_down(dev);
+		vortex_down(dev, 1);
 
 	if (vortex_debug > 1) {
 		printk(KERN_DEBUG"%s: vortex_close() status %4.4x, Tx status %2.2x.\n",
@@ -2567,7 +2661,6 @@ vortex_close(struct net_device *dev)
 			((vp->drv_flags & HAS_HWCKSM) == 0) &&
 			(hw_checksums[vp->card_idx] == -1)) {
 		printk(KERN_WARNING "%s supports hardware checksums, and we're not using them!\n", dev->name);
-		printk(KERN_WARNING "Please see http://www.uow.edu.au/~andrewm/zerocopy.html\n");
 	}
 #endif
 		
@@ -2576,10 +2669,10 @@ vortex_close(struct net_device *dev)
 	if (vp->full_bus_master_rx) { /* Free Boomerang bus master Rx buffers. */
 		for (i = 0; i < RX_RING_SIZE; i++)
 			if (vp->rx_skbuff[i]) {
-				pci_unmap_single(	vp->pdev, le32_to_cpu(vp->rx_ring[i].addr),
+				pci_unmap_single(	VORTEX_PCI(vp), le32_to_cpu(vp->rx_ring[i].addr),
 									PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
 				dev_kfree_skb(vp->rx_skbuff[i]);
-				vp->rx_skbuff[i] = 0;
+				vp->rx_skbuff[i] = NULL;
 			}
 	}
 	if (vp->full_bus_master_tx) { /* Free Boomerang bus master Tx buffers. */
@@ -2590,15 +2683,15 @@ vortex_close(struct net_device *dev)
 				int k;
 
 				for (k=0; k<=skb_shinfo(skb)->nr_frags; k++)
-						pci_unmap_single(vp->pdev,
+						pci_unmap_single(VORTEX_PCI(vp),
 										 le32_to_cpu(vp->tx_ring[i].frag[k].addr),
 										 le32_to_cpu(vp->tx_ring[i].frag[k].length)&0xFFF,
 										 PCI_DMA_TODEVICE);
 #else
-				pci_unmap_single(vp->pdev, le32_to_cpu(vp->tx_ring[i].addr), skb->len, PCI_DMA_TODEVICE);
+				pci_unmap_single(VORTEX_PCI(vp), le32_to_cpu(vp->tx_ring[i].addr), skb->len, PCI_DMA_TODEVICE);
 #endif
 				dev_kfree_skb(skb);
-				vp->tx_skbuff[i] = 0;
+				vp->tx_skbuff[i] = NULL;
 			}
 		}
 	}
@@ -2610,7 +2703,7 @@ static void
 dump_tx_ring(struct net_device *dev)
 {
 	if (vortex_debug > 0) {
-		struct vortex_private *vp = (struct vortex_private *)dev->priv;
+	struct vortex_private *vp = netdev_priv(dev);
 		long ioaddr = dev->base_addr;
 		
 		if (vp->full_bus_master_tx) {
@@ -2643,7 +2736,7 @@ dump_tx_ring(struct net_device *dev)
 
 static struct net_device_stats *vortex_get_stats(struct net_device *dev)
 {
-	struct vortex_private *vp = (struct vortex_private *)dev->priv;
+	struct vortex_private *vp = netdev_priv(dev);
 	unsigned long flags;
 
 	if (netif_device_present(dev)) {	/* AKPM: Used to be netif_running */
@@ -2663,7 +2756,7 @@ static struct net_device_stats *vortex_g
 	*/
 static void update_stats(long ioaddr, struct net_device *dev)
 {
-	struct vortex_private *vp = (struct vortex_private *)dev->priv;
+	struct vortex_private *vp = netdev_priv(dev);
 	int old_window = inw(ioaddr + EL3_CMD);
 
 	if (old_window == 0xffff)	/* Chip suspended or ejected. */
@@ -2700,29 +2793,32 @@ static void update_stats(long ioaddr, st
 	return;
 }
 
+
 static void vortex_get_drvinfo(struct net_device *dev,
-				struct ethtool_drvinfo *info)
+					struct ethtool_drvinfo *info)
 {
-	struct vortex_private *vp = dev->priv;
+	struct vortex_private *vp = netdev_priv(dev);
 
 	strcpy(info->driver, DRV_NAME);
 	strcpy(info->version, DRV_VERSION);
-	if (vp->pdev)
-		strcpy(info->bus_info, pci_name(vp->pdev));
-	else
+	if (VORTEX_PCI(vp)) {
+		strcpy(info->bus_info, pci_name(VORTEX_PCI(vp)));
+	} else {
 		sprintf(info->bus_info, "EISA 0x%lx %d",
 			dev->base_addr, dev->irq);
+	}
 }
 
 static struct ethtool_ops vortex_ethtool_ops = {
 	.get_drvinfo		= vortex_get_drvinfo,
 };
 
-static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+#ifdef CONFIG_PCI
+static int vortex_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-	struct vortex_private *vp = (struct vortex_private *)dev->priv;
+	struct vortex_private *vp = netdev_priv(dev);
 	long ioaddr = dev->base_addr;
-	struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data;
+	struct mii_ioctl_data *data = if_mii(rq);
 	int phy = vp->phys[0] & 0x1f;
 	int retval;
 
@@ -2756,6 +2852,31 @@ static int vortex_ioctl(struct net_devic
 	return retval;
 }
 
+/*
+ *	Must power the device up to do MDIO operations
+ */
+static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	int err;
+	struct vortex_private *vp = netdev_priv(dev);
+	int state = 0;
+
+	if (vp && VORTEX_PCI(vp))
+		state = VORTEX_PCI(vp)->current_state;
+
+	/* The kernel core really should have pci_get_power_state() */
+
+	if(state != 0)
+		pci_set_power_state(VORTEX_PCI(vp), 0);
+	err = vortex_do_ioctl(dev, rq, cmd);
+	if(state != 0)
+		pci_set_power_state(VORTEX_PCI(vp), state);
+
+	return err;
+}
+#endif
+
+
 /* Pre-Cyclone chips have no documented multicast filter, so the only
    multicast setting is to receive all multicast frames.  At least
    the chip has a very clean way to set the mode, unlike many others. */
@@ -2776,6 +2897,61 @@ static void set_rx_mode(struct net_devic
 	outw(new_mode, ioaddr + EL3_CMD);
 }
 
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+/* Setup the card so that it can receive frames with an 802.1q VLAN tag.
+   Note that this must be done after each RxReset due to some backwards
+   compatibility logic in the Cyclone and Tornado ASICs */
+
+/* The Ethernet Type used for 802.1q tagged frames */
+#define VLAN_ETHER_TYPE 0x8100
+
+static void set_8021q_mode(struct net_device *dev, int enable)
+{
+	struct vortex_private *vp = (struct vortex_private *)dev->priv;
+	long ioaddr = dev->base_addr;
+	int old_window = inw(ioaddr + EL3_CMD);
+	int mac_ctrl;
+
+	if ((vp->drv_flags&IS_CYCLONE) || (vp->drv_flags&IS_TORNADO)) {
+		/* cyclone and tornado chipsets can recognize 802.1q
+		 * tagged frames and treat them correctly */
+
+		int max_pkt_size = dev->mtu+14;	/* MTU+Ethernet header */
+		if (enable)
+			max_pkt_size += 4;	/* 802.1Q VLAN tag */
+
+		EL3WINDOW(3);
+		outw(max_pkt_size, ioaddr+Wn3_MaxPktSize);
+
+		/* set VlanEtherType to let the hardware checksumming
+		   treat tagged frames correctly */
+		EL3WINDOW(7);
+		outw(VLAN_ETHER_TYPE, ioaddr+Wn7_VlanEtherType);
+	} else {
+		/* on older cards we have to enable large frames */
+
+		vp->large_frames = dev->mtu > 1500 || enable;
+
+		EL3WINDOW(3);
+		mac_ctrl = inw(ioaddr+Wn3_MAC_Ctrl);
+		if (vp->large_frames)
+			mac_ctrl |= 0x40;
+		else
+			mac_ctrl &= ~0x40;
+		outw(mac_ctrl, ioaddr+Wn3_MAC_Ctrl);
+	}
+
+	EL3WINDOW(old_window);
+}
+#else
+
+static void set_8021q_mode(struct net_device *dev, int enable)
+{
+}
+
+
+#endif
+
 /* MII transceiver control section.
    Read and write the MII registers using software-generated serial
    MDIO protocol.  See the MII specifications or DP83840A data sheet
@@ -2810,7 +2986,7 @@ static void mdio_sync(long ioaddr, int b
 
 static int mdio_read(struct net_device *dev, int phy_id, int location)
 {
-	struct vortex_private *vp = (struct vortex_private *)dev->priv;
+	struct vortex_private *vp = netdev_priv(dev);
 	int i;
 	long ioaddr = dev->base_addr;
 	int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
@@ -2844,7 +3020,7 @@ static int mdio_read(struct net_device *
 
 static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
 {
-	struct vortex_private *vp = (struct vortex_private *)dev->priv;
+	struct vortex_private *vp = netdev_priv(dev);
 	long ioaddr = dev->base_addr;
 	int write_cmd = 0x50020000 | (phy_id << 23) | (location << 18) | value;
 	long mdio_addr = ioaddr + Wn4_PhysicalMgmt;
@@ -2878,7 +3054,7 @@ static void mdio_write(struct net_device
 /* Set Wake-On-LAN mode and put the board into D3 (power-down) state. */
 static void acpi_set_WOL(struct net_device *dev)
 {
-	struct vortex_private *vp = (struct vortex_private *)dev->priv;
+	struct vortex_private *vp = netdev_priv(dev);
 	long ioaddr = dev->base_addr;
 
 	/* Power up on: 1==Downloaded Filter, 2==Magic Packets, 4==Link Status. */
@@ -2889,8 +3065,8 @@ static void acpi_set_WOL(struct net_devi
 	outw(RxEnable, ioaddr + EL3_CMD);
 
 	/* Change the power state to D3; RxEnable doesn't take effect. */
-	pci_enable_wake(vp->pdev, 0, 1);
-	pci_set_power_state(vp->pdev, 3);
+	pci_enable_wake(VORTEX_PCI(vp), 0, 1);
+	pci_set_power_state(VORTEX_PCI(vp), 3);
 }
 
 
@@ -2904,21 +3080,21 @@ static void __devexit vortex_remove_one 
 		BUG();
 	}
 
-	vp = dev->priv;
+	vp = netdev_priv(dev);
 
 	/* AKPM: FIXME: we should have
 	 *	if (vp->cb_fn_base) iounmap(vp->cb_fn_base);
 	 * here
 	 */
 	unregister_netdev(dev);
-	/* Should really use issue_and_wait() here */
-	outw(TotalReset|0x14, dev->base_addr + EL3_CMD);
 
-	if (vp->pdev && vp->enable_wol) {
-		pci_set_power_state(vp->pdev, 0);	/* Go active */
+	if (VORTEX_PCI(vp) && vp->enable_wol) {
+		pci_set_power_state(VORTEX_PCI(vp), 0);	/* Go active */
 		if (vp->pm_state_valid)
-			pci_restore_state(vp->pdev, vp->power_state);
+			pci_restore_state(VORTEX_PCI(vp), vp->power_state);
 	}
+	/* Should really use issue_and_wait() here */
+	outw(TotalReset|0x14, dev->base_addr + EL3_CMD);
 
 	pci_free_consistent(pdev,
 						sizeof(struct boom_rx_desc) * RX_RING_SIZE
@@ -2927,18 +3103,18 @@ static void __devexit vortex_remove_one 
 						vp->rx_ring_dma);
 	if (vp->must_free_region)
 		release_region(dev->base_addr, vp->io_size);
-	kfree(dev);
+	free_netdev(dev);
 }
 
 
 static struct pci_driver vortex_driver = {
-	name:		"3c59x",
-	probe:		vortex_init_one,
-	remove:		__devexit_p(vortex_remove_one),
-	id_table:	vortex_pci_tbl,
+	.name		= "3c59x",
+	.probe		= vortex_init_one,
+	.remove		= __devexit_p(vortex_remove_one),
+	.id_table	= vortex_pci_tbl,
 #ifdef CONFIG_PM
-	suspend:	vortex_suspend,
-	resume:		vortex_resume,
+	.suspend	= vortex_suspend,
+	.resume		= vortex_resume,
 #endif
 };
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/net/dl2k.c linux-2.4.29-pre3/drivers/net/dl2k.c
--- linux-2.4.28/drivers/net/dl2k.c	2003-06-13 14:51:34.000000000 +0000
+++ linux-2.4.29-pre3/drivers/net/dl2k.c	2004-12-22 16:06:30.272695792 +0000
@@ -1,7 +1,8 @@
 /*  D-Link DL2000-based Gigabit Ethernet Adapter Linux driver */
 /*
     Copyright (c) 2001, 2002 by D-Link Corporation
-    Written by Edward Peng.<edward_peng@dlink.com.tw>
+    Copyright (c) 2003 by Alpha Networks
+    Written by Edward Peng.<edward_peng@alphanetworks.com>
     Created 03-May-2001, base on Linux' sundance.c.
 
     This program is free software; you can redistribute it and/or modify
@@ -47,12 +48,17 @@
     1.17	2002/10/03	Fix RMON statistics overflow. 
 			     	Always use I/O mapping to access eeprom, 
 				avoid system freezing with some chipsets.
+    1.18	2002/11/07	New tx scheme, adaptive tx_coalesce.
+    				Remove tx_coalesce option.
+    1.19	2003/12/16	Fix problem parsing the eeprom on big endian
+    				systems. (philt@4bridgeworks.com)
 
 */
 #define DRV_NAME	"D-Link DL2000-based linux driver"
-#define DRV_VERSION	"v1.17a"
-#define DRV_RELDATE	"2002/10/04"
+#define DRV_VERSION	"v1.19"
+#define DRV_RELDATE	"2003/12/16"
 #include "dl2k.h"
+#include <linux/version.h>
 
 static char version[] __devinitdata =
       KERN_INFO DRV_NAME " " DRV_VERSION " " DRV_RELDATE "\n";	
@@ -64,9 +70,8 @@ static char *media[MAX_UNITS];
 static int tx_flow=-1;
 static int rx_flow=-1;
 static int copy_thresh;
-static int rx_coalesce=10;	/* Rx frame count each interrupt */
+static int rx_coalesce=0;	/* Rx frame count each interrupt */
 static int rx_timeout=200;	/* Rx DMA wait time in 640ns increments */
-static int tx_coalesce=16;	/* HW xmit count each TxDMAComplete */
 
 
 MODULE_AUTHOR ("Edward Peng");
@@ -81,12 +86,11 @@ MODULE_PARM (rx_flow, "i");
 MODULE_PARM (copy_thresh, "i");
 MODULE_PARM (rx_coalesce, "i");	/* Rx frame count each interrupt */
 MODULE_PARM (rx_timeout, "i");	/* Rx DMA wait time in 64ns increments */
-MODULE_PARM (tx_coalesce, "i"); /* HW xmit count each TxDMAComplete */
 
 
 /* Enable the default interrupts */
 #define DEFAULT_INTR (RxDMAComplete | HostError | IntRequested | TxDMAComplete| \
-       UpdateStats | LinkEvent)
+       UpdateStats | LinkEvent|TxComplete)
 #define EnableInt() \
 writew(DEFAULT_INTR, ioaddr + IntEnable)
 
@@ -97,11 +101,19 @@ static int rio_open (struct net_device *
 static void rio_timer (unsigned long data);
 static void rio_tx_timeout (struct net_device *dev);
 static void alloc_list (struct net_device *dev);
+static void tx_poll (unsigned long data);
 static int start_xmit (struct sk_buff *skb, struct net_device *dev);
-static void rio_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
-static void rio_free_tx (struct net_device *dev, int irq);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,69)
+static irqreturn_t 
+rio_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
+#else
+static void 
+rio_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
+#endif
+static void rio_free_tx (struct net_device *dev);
 static void tx_error (struct net_device *dev, int tx_status);
-static int receive_packet (struct net_device *dev);
+static void rx_poll (unsigned long data);
+static void refill_rx (struct net_device *dev);
 static void rio_error (struct net_device *dev, int int_status);
 static int change_mtu (struct net_device *dev, int new_mtu);
 static void set_multicast (struct net_device *dev);
@@ -172,10 +184,11 @@ rio_probe1 (struct pci_dev *pdev, const 
 	np->pdev = pdev;
 	spin_lock_init (&np->tx_lock);
 	spin_lock_init (&np->rx_lock);
+	tasklet_init(&np->tx_tasklet, tx_poll, (unsigned long) dev);
+	tasklet_init(&np->rx_tasklet, rx_poll, (unsigned long) dev);
 
 	/* Parse manual configuration */
 	np->an_enable = 1;
-	np->tx_coalesce = 1;
 	if (card_idx < MAX_UNITS) {
 		if (media[card_idx] != NULL) {
 			np->an_enable = 0;
@@ -229,10 +242,6 @@ rio_probe1 (struct pci_dev *pdev, const 
 		np->tx_flow = (tx_flow == 0) ? 0 : 1;
 		np->rx_flow = (rx_flow == 0) ? 0 : 1;
 
-		if (tx_coalesce < 1)
-			tx_coalesce = 1;
-		else if (tx_coalesce > TX_RING_SIZE-1)
-			tx_coalesce = TX_RING_SIZE - 1;
 	}
 	dev->open = &rio_open;
 	dev->hard_start_xmit = &start_xmit;
@@ -297,9 +306,6 @@ rio_probe1 (struct pci_dev *pdev, const 
 		dev->name, np->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], irq);
-	if (tx_coalesce > 1)
-		printk(KERN_INFO "tx_coalesce:\t%d packets\n", 
-				tx_coalesce);
 	if (np->coalesce)
 		printk(KERN_INFO "rx_coalesce:\t%d packets\n"
 		       KERN_INFO "rx_timeout: \t%d ns\n", 
@@ -370,8 +376,9 @@ parse_eeprom (struct net_device *dev)
 #endif
 	/* Read eeprom */
 	for (i = 0; i < 128; i++) {
-		((u16 *) sromdata)[i] = le16_to_cpu (read_eeprom (ioaddr, i));
+		((u16 *) sromdata)[i] = cpu_to_le16 (read_eeprom (ioaddr, i));
 	}
+	psrom->crc = le32_to_cpu(psrom->crc);
 #ifdef	MEM_MAPPING
 	ioaddr = dev->base_addr;
 #endif	
@@ -469,9 +476,12 @@ rio_open (struct net_device *dev)
 	writeb (0x30, ioaddr + RxDMABurstThresh);
 	writeb (0x30, ioaddr + RxDMAUrgentThresh);
 	writel (0x0007ffff, ioaddr + RmonStatMask);
+
 	/* clear statistics */
 	clear_stats (dev);
 
+	atomic_set(&np->tx_desc_lock, 0);
+
 	/* VLAN supported */
 	if (np->vlan) {
 		/* priority field in RxDMAIntCtrl  */
@@ -556,17 +566,31 @@ rio_timer (unsigned long data)
 	np->timer.expires = jiffies + next_tick;
 	add_timer(&np->timer);
 }
-	
+
 static void
 rio_tx_timeout (struct net_device *dev)
 {
+	struct netdev_private *np = dev->priv;
 	long ioaddr = dev->base_addr;
 
-	printk (KERN_INFO "%s: Tx timed out (%4.4x), is buffer full?\n",
+	printk (KERN_INFO "%s: Tx timed out (%4.4x), "
+			"clean up tx queue to restart..\n",
 		dev->name, readl (ioaddr + TxStatus));
-	rio_free_tx(dev, 0);
+	printk (KERN_INFO "%s: cur_tx=%lx cur_task=%lx old_tx=%lx "
+			"TFDListPtr=%08x tx_full=%d",
+			dev->name, np->cur_tx, np->cur_task, np->old_tx,
+			readl(ioaddr + TFDListPtr0),
+			netif_queue_stopped(dev));
+	writew(0, ioaddr + IntEnable);
+	writew(0, ioaddr + TFDListPtr0);
+	writew(0, ioaddr + TFDListPtr1);
+	tasklet_disable(&np->tx_tasklet);
+	rio_free_tx(dev);
 	dev->if_port = 0;
 	dev->trans_start = jiffies;
+	tasklet_enable(&np->tx_tasklet);
+	writew(DEFAULT_INTR, ioaddr + IntEnable);
+	return;
 }
 
  /* allocate and initialize Tx and Rx descriptors */
@@ -578,6 +602,7 @@ alloc_list (struct net_device *dev)
 
 	np->cur_rx = np->cur_tx = 0;
 	np->old_rx = np->old_tx = 0;
+	np->cur_task = 0;
 	np->rx_buf_sz = (dev->mtu <= 1500 ? PACKET_SIZE : dev->mtu + 32);
 
 	/* Initialize Tx descriptors, TFDListPtr leaves in start_xmit(). */
@@ -627,6 +652,31 @@ alloc_list (struct net_device *dev)
 	return;
 }
 
+static void tx_poll (unsigned long data)
+{
+	struct net_device *dev = (struct net_device*) data;
+	struct netdev_private *np = dev->priv;
+	unsigned head = np->cur_task % TX_RING_SIZE;
+	struct netdev_desc *txdesc = 
+		&np->tx_ring[(np->cur_tx + TX_RING_SIZE - 1) % TX_RING_SIZE];
+
+	/* Indicate the latest descriptor of tx ring */
+	txdesc->status |= cpu_to_le64 (TxDMAIndicate);
+	
+	while ((np->cur_task + TX_RING_SIZE - np->cur_tx) % TX_RING_SIZE > 0) {
+		txdesc = &np->tx_ring[np->cur_task];
+		txdesc->status &= cpu_to_le64 (~TFDDone);
+		np->cur_task = (np->cur_task + 1) % TX_RING_SIZE;
+	}
+
+	if (readl (dev->base_addr + TFDListPtr0) == 0) {
+		writel (np->tx_ring_dma + head * sizeof (struct netdev_desc),
+			dev->base_addr + TFDListPtr0);
+		writel (0, dev->base_addr + TFDListPtr1);
+	}
+
+	return;
+}
 static int
 start_xmit (struct sk_buff *skb, struct net_device *dev)
 {
@@ -665,48 +715,60 @@ start_xmit (struct sk_buff *skb, struct 
 
 	/* DL2K bug: DMA fails to get next descriptor ptr in 10Mbps mode
 	 * Work around: Always use 1 descriptor in 10Mbps mode */
-	if (entry % np->tx_coalesce == 0 || np->speed == 10)
-		txdesc->status = cpu_to_le64 (entry | tfc_vlan_tag |
+	if (np->speed == 10) {
+		/* Note the order! Stop queue before hardware processing
+		 * this descriptor */
+		netif_stop_queue (dev);
+		txdesc->status = cpu_to_le64 (entry | tfc_vlan_tag | 
 					      WordAlignDisable | 
-					      TxDMAIndicate |
+					      TxDMAIndicate | TxComplete |
 					      (1 << FragCountShift));
-	else
-		txdesc->status = cpu_to_le64 (entry | tfc_vlan_tag |
+		/* TxDMAPollNow */
+		writel(readl(ioaddr + DMACtrl) | 0x00001000, ioaddr + DMACtrl);
+		if (readl (dev->base_addr + TFDListPtr0) == 0) {
+			writel (np->tx_ring_dma + 
+				entry * sizeof (struct netdev_desc),
+				dev->base_addr + TFDListPtr0);
+			writel (0, dev->base_addr + TFDListPtr1);
+		}
+		np->cur_tx = np->cur_task = (np->cur_tx + 1) % TX_RING_SIZE;
+	} else {
+		np->cur_tx = (np->cur_tx + 1) % TX_RING_SIZE;
+		mb();
+		txdesc->status = cpu_to_le64 (entry | tfc_vlan_tag | TFDDone |
 					      WordAlignDisable | 
 					      (1 << FragCountShift));
-
-	/* TxDMAPollNow */
-	writel (readl (ioaddr + DMACtrl) | 0x00001000, ioaddr + DMACtrl);
-	/* Schedule ISR */
-	writel(10000, ioaddr + CountDown);
-	np->cur_tx = (np->cur_tx + 1) % TX_RING_SIZE;
-	if ((np->cur_tx - np->old_tx + TX_RING_SIZE) % TX_RING_SIZE
-			< TX_QUEUE_LEN - 1 && np->speed != 10) {
-		/* do nothing */
-	} else if (!netif_queue_stopped(dev)) {
-		netif_stop_queue (dev);
+		tasklet_schedule (&np->tx_tasklet);
+		/* Schedule ISR */
+		if ((np->cur_tx - np->old_tx + TX_RING_SIZE) % TX_RING_SIZE
+				< TX_QUEUE_LEN - 1) {
+			/* do nothing */
+		} else if (!netif_queue_stopped(dev)) {
+			netif_stop_queue (dev);
+		}
 	}
 
-	/* The first TFDListPtr */
-	if (readl (dev->base_addr + TFDListPtr0) == 0) {
-		writel (np->tx_ring_dma + entry * sizeof (struct netdev_desc),
-			dev->base_addr + TFDListPtr0);
-		writel (0, dev->base_addr + TFDListPtr1);
-	}
-	
+
 	/* NETDEV WATCHDOG timer */
 	dev->trans_start = jiffies;
 	return 0;
 }
-
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,69))
+static irqreturn_t
+rio_interrupt (int irq, void *dev_instance, struct pt_regs *rgs)
+#else
 static void
 rio_interrupt (int irq, void *dev_instance, struct pt_regs *rgs)
+#endif
 {
 	struct net_device *dev = dev_instance;
 	struct netdev_private *np;
 	unsigned int_status;
 	long ioaddr;
 	int cnt = max_intrloop;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,69))
+	int handled = 0;
+#endif
 
 	ioaddr = dev->base_addr;
 	np = dev->priv;
@@ -716,17 +778,26 @@ rio_interrupt (int irq, void *dev_instan
 		int_status &= DEFAULT_INTR;
 		if (int_status == 0 || --cnt < 0)
 			break;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,69))
+		handled = 1;
+#endif
 		/* Processing received packets */
-		if (int_status & RxDMAComplete)
-			receive_packet (dev);
+		if (int_status & RxDMAComplete) {
+			writew(DEFAULT_INTR & ~(RxDMAComplete | RxComplete), 
+					ioaddr + IntEnable);
+			if (np->budget < 0) {
+				np->budget = RX_BUDGET;
+			}
+			tasklet_schedule (&np->rx_tasklet);
+		}
 		/* TxDMAComplete interrupt */
-		if ((int_status & (TxDMAComplete|IntRequested))) {
+		if ((int_status & (TxDMAComplete|IntRequested|TxComplete))) {
 			int tx_status;
 			tx_status = readl (ioaddr + TxStatus);
 			if (tx_status & 0x01)
 				tx_error (dev, tx_status);
 			/* Free used tx skbuffs */
-			rio_free_tx (dev, 1);		
+			rio_free_tx (dev);		
 		}
 
 		/* Handle uncommon events */
@@ -734,25 +805,30 @@ rio_interrupt (int irq, void *dev_instan
 		    (HostError | LinkEvent | UpdateStats))
 			rio_error (dev, int_status);
 	}
-	if (np->cur_tx != np->old_tx)
-		writel (100, ioaddr + CountDown);
+	writel(5000, ioaddr + CountDown);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,69))
+	return 	IRQ_RETVAL(handled);
+#endif
 }
 
 static void 
-rio_free_tx (struct net_device *dev, int irq) 
+rio_free_tx (struct net_device *dev) 
 {
 	struct netdev_private *np = (struct netdev_private *) dev->priv;
 	int entry = np->old_tx % TX_RING_SIZE;
-	int tx_use = 0;
-	long flag = 0;
+	unsigned long flag = 0;
+	int irq = in_interrupt();
+
+	if (atomic_read(&np->tx_desc_lock))
+		return;
+	atomic_inc(&np->tx_desc_lock);
 	
 	if (irq)
 		spin_lock(&np->tx_lock);
 	else
 		spin_lock_irqsave(&np->tx_lock, flag);
-			
 	/* Free used tx skbuffs */
-	while (entry != np->cur_tx) {
+	while (entry != np->cur_task) {
 		struct sk_buff *skb;
 
 		if (!(np->tx_ring[entry].status & TFDDone))
@@ -768,8 +844,8 @@ rio_free_tx (struct net_device *dev, int
 
 		np->tx_skbuff[entry] = 0;
 		entry = (entry + 1) % TX_RING_SIZE;
-		tx_use++;
 	}
+
 	if (irq)
 		spin_unlock(&np->tx_lock);
 	else
@@ -778,12 +854,19 @@ rio_free_tx (struct net_device *dev, int
 
 	/* If the ring is no longer full, clear tx_full and 
 	   call netif_wake_queue() */
-
-	if (netif_queue_stopped(dev) &&
+	if (np->speed != 10) {
+		if (netif_queue_stopped(dev) &&
 	    ((np->cur_tx - np->old_tx + TX_RING_SIZE) % TX_RING_SIZE 
-	    < TX_QUEUE_LEN - 1 || np->speed == 10)) {
+	    < TX_QUEUE_LEN - 1)) {
 		netif_wake_queue (dev);
+		}
+	}
+	else {
+		if (netif_queue_stopped(dev) && 
+	    		np->cur_tx == np->old_tx) 
+		netif_wake_queue(dev);
 	}
+	atomic_dec(&np->tx_desc_lock);
 }
 
 static void
@@ -814,7 +897,7 @@ tx_error (struct net_device *dev, int tx
 				break;
 			mdelay (1);
 		}
-		rio_free_tx (dev, 1);
+		rio_free_tx (dev);
 		/* Reset TFDListPtr */
 		writel (np->tx_ring_dma +
 			np->old_tx * sizeof (struct netdev_desc),
@@ -848,28 +931,34 @@ tx_error (struct net_device *dev, int tx
 	writel (readw (dev->base_addr + MACCtrl) | TxEnable, ioaddr + MACCtrl);
 }
 
-static int
-receive_packet (struct net_device *dev)
+static void rx_poll (unsigned long data)
 {
+	struct net_device *dev = (struct net_device*) data;
 	struct netdev_private *np = (struct netdev_private *) dev->priv;
 	int entry = np->cur_rx % RX_RING_SIZE;
-	int cnt = 30;
-
+	int cnt = np->budget;
+	long ioaddr = dev->base_addr;
+	int received = 0;
 	/* If RFDDone, FrameStart and FrameEnd set, there is a new packet in. */
 	while (1) {
 		struct netdev_desc *desc = &np->rx_ring[entry];
 		int pkt_len;
 		u64 frame_status;
 
-		if (!(desc->status & RFDDone) ||
-		    !(desc->status & FrameStart) || !(desc->status & FrameEnd))
-			break;
+		if (--cnt < 0) {
+			np->cur_rx = entry;
+			goto not_done;
+		}
 
 		/* Chip omits the CRC. */
 		pkt_len = le64_to_cpu (desc->status & 0xffff);
 		frame_status = le64_to_cpu (desc->status);
-		if (--cnt < 0)
+
+		if (!(desc->status & RFDDone) ||
+		    !(desc->status & FrameStart) || !(desc->status & FrameEnd))
 			break;
+		
+
 		pci_dma_sync_single (np->pdev, desc->fraginfo, np->rx_buf_sz,
 				     PCI_DMA_FROMDEVICE);
 		/* Update rx error statistics, drop packet. */
@@ -914,9 +1003,37 @@ receive_packet (struct net_device *dev)
 			dev->last_rx = jiffies;
 		}
 		entry = (entry + 1) % RX_RING_SIZE;
+		received++;
 	}
-	spin_lock(&np->rx_lock);
 	np->cur_rx = entry;
+	refill_rx (dev);
+	np->budget -= received;
+	writew (DEFAULT_INTR, ioaddr + IntEnable);
+	return;
+	
+not_done:
+	refill_rx (dev);
+	if (!received)
+		received = 1;
+	np->budget -= received;
+	if (np->budget <= 0)
+		np->budget = RX_BUDGET;
+	tasklet_schedule (&np->rx_tasklet);
+	return;
+}
+
+static void refill_rx (struct net_device *dev) 
+{
+	struct netdev_private *np = dev->priv;
+	int entry;
+	int irq = in_interrupt();
+	unsigned long flag = 0;
+
+	if (irq)
+		spin_lock(&np->rx_lock);
+	else
+		spin_lock_irqsave(&np->rx_lock, flag);
+
 	/* Re-allocate skbuffs to fill the descriptor ring */
 	entry = np->old_rx;
 	while (entry != np->cur_rx) {
@@ -947,8 +1064,12 @@ receive_packet (struct net_device *dev)
 		entry = (entry + 1) % RX_RING_SIZE;
 	}
 	np->old_rx = entry;
-	spin_unlock(&np->rx_lock);
-	return 0;
+
+	if (irq)
+		spin_unlock(&np->rx_lock);
+	else
+		spin_unlock_irqrestore(&np->rx_lock, flag);
+	return;
 }
 
 static void
@@ -966,10 +1087,6 @@ rio_error (struct net_device *dev, int i
 				mii_get_media_pcs (dev);
 			else
 				mii_get_media (dev);
-			if (np->speed == 1000)
-				np->tx_coalesce = tx_coalesce;
-			else 
-				np->tx_coalesce = 1;
 			macctrl = 0;
 			macctrl |= (np->vlan) ? AutoVLANuntagging : 0;
 			macctrl |= (np->full_duplex) ? DuplexSelect : 0;
@@ -1007,10 +1124,10 @@ get_stats (struct net_device *dev)
 {
 	long ioaddr = dev->base_addr;
 	struct netdev_private *np = dev->priv;
+	unsigned int stat_reg;
 #ifdef MEM_MAPPING
 	int i;
 #endif
-	unsigned int stat_reg;
 
 	/* All statistics registers need to be acknowledged,
 	   else statistic overflow could cause problems */
@@ -1051,7 +1168,6 @@ get_stats (struct net_device *dev)
 	readw (ioaddr + BcstFramesXmtdOk);
 	readw (ioaddr + MacControlFramesXmtd);
 	readw (ioaddr + FramesWEXDeferal);
-
 #ifdef MEM_MAPPING
 	for (i = 0x100; i <= 0x150; i += 4)
 		readl (ioaddr + i);
@@ -1070,7 +1186,7 @@ clear_stats (struct net_device *dev)
 	long ioaddr = dev->base_addr;
 #ifdef MEM_MAPPING
 	int i;
-#endif 
+#endif
 
 	/* All statistics registers need to be acknowledged,
 	   else statistic overflow could cause problems */
@@ -1109,7 +1225,7 @@ clear_stats (struct net_device *dev)
 #ifdef MEM_MAPPING
 	for (i = 0x100; i <= 0x150; i += 4)
 		readl (ioaddr + i);
-#endif 
+#endif
 	readw (ioaddr + TxJumboFrames);
 	readw (ioaddr + RxJumboFrames);
 	readw (ioaddr + TCPCheckSumErrors);
@@ -1140,10 +1256,6 @@ set_multicast (struct net_device *dev)
 	long ioaddr = dev->base_addr;
 	u32 hash_table[2];
 	u16 rx_mode = 0;
-	int i;
-	int bit;
-	int index, crc;
-	struct dev_mc_list *mclist;
 	struct netdev_private *np = dev->priv;
 	
 	hash_table[0] = hash_table[1] = 0;
@@ -1157,6 +1269,8 @@ set_multicast (struct net_device *dev)
 		/* Receive broadcast and multicast frames */
 		rx_mode = ReceiveBroadcast | ReceiveMulticast | ReceiveUnicast;
 	} else if (dev->mc_count > 0) {
+		int i;
+		struct dev_mc_list *mclist;
 		/* Receive broadcast frames and multicast frames filtering 
 		   by Hashtable */
 		rx_mode =
@@ -1164,14 +1278,13 @@ set_multicast (struct net_device *dev)
 		for (i=0, mclist = dev->mc_list; mclist && i < dev->mc_count; 
 				i++, mclist=mclist->next) 
 		{
-			crc = ether_crc_le (ETH_ALEN, mclist->dmi_addr);
+			int bit, index = 0;
+			int crc = ether_crc_le (ETH_ALEN, mclist->dmi_addr);
 			/* The inverted high significant 6 bits of CRC are
 			   used as an index to hashtable */
-			for (index=0, bit=0; bit < 6; bit++) {
-				if (test_bit(31-bit, &crc)) {
-					 set_bit(bit, &index);
-				}
-			}
+			for (bit = 0; bit < 6; bit++)
+				if (crc & (1 << (31 - bit)))
+					index |= (1 << bit);
 			hash_table[index / 32] |= (1 << (index % 32));
 		}
 	} else {
@@ -1798,7 +1911,13 @@ rio_close (struct net_device *dev)
 
 	/* Stop Tx and Rx logics */
 	writel (TxDisable | RxDisable | StatsDisable, ioaddr + MACCtrl);
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
 	synchronize_irq ();
+#else
+	synchronize_irq(dev->irq);
+#endif
+	tasklet_kill (&np->tx_tasklet);
+	tasklet_kill (&np->rx_tasklet);
 	free_irq (dev->irq, dev);
 	del_timer_sync (&np->timer);
 	
@@ -1851,10 +1970,10 @@ rio_remove1 (struct pci_dev *pdev)
 }
 
 static struct pci_driver rio_driver = {
-	name:		"dl2k",
-	id_table:	rio_pci_tbl,
-	probe:		rio_probe1,
-	remove:		__devexit_p(rio_remove1),
+	.name		= "dl2k",
+	.id_table	= rio_pci_tbl,
+	.probe		= rio_probe1,
+	.remove		= __devexit_p(rio_remove1),
 };
 
 static int __init
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/net/dl2k.h linux-2.4.29-pre3/drivers/net/dl2k.h
--- linux-2.4.28/drivers/net/dl2k.h	2003-08-25 11:44:42.000000000 +0000
+++ linux-2.4.29-pre3/drivers/net/dl2k.h	2004-12-22 16:07:37.152528512 +0000
@@ -26,7 +26,6 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/init.h>
-#include <linux/crc32.h>
 #include <linux/ethtool.h>
 #include <asm/processor.h>	/* Processor type for cache alignment. */
 #include <asm/bitops.h>
@@ -35,8 +34,16 @@
 #include <linux/delay.h>
 #include <linux/spinlock.h>
 #include <linux/time.h>
+#ifdef DL2K_COMPAT_WITH_OLD_KERNEL
+#include "crc32.h"
+#else
+#include <linux/crc32.h>
+#endif
+
+
+
 #define TX_RING_SIZE	256
-#define TX_QUEUE_LEN	(TX_RING_SIZE - 1) /* Limit ring entries actually used.*/
+#define TX_QUEUE_LEN	(TX_RING_SIZE - 10) /* Limit ring entries actually used.*/
 #define RX_RING_SIZE 	256
 #define TX_TOTAL_SIZE	TX_RING_SIZE*sizeof(struct netdev_desc)
 #define RX_TOTAL_SIZE	RX_RING_SIZE*sizeof(struct netdev_desc)
@@ -512,7 +519,7 @@ typedef union t_MII_ESR {
 	u16 image;
 	struct {
 		u16 _bit_11_0:12;	// bit 11:0
-		u16 media_1000BT_HD:2;	// bit 12
+		u16 media_1000BT_HD:1;	// bit 12
 		u16 media_1000BT_FD:1;	// bit 13
 		u16 media_1000BX_HD:1;	// bit 14
 		u16 media_1000BX_FD:1;	// bit 15
@@ -655,6 +662,8 @@ struct netdev_private {
 	struct net_device_stats stats;
 	unsigned int rx_buf_sz;		/* Based on MTU+slack. */
 	unsigned int speed;		/* Operating speed */
+	struct tasklet_struct tx_tasklet;
+	struct tasklet_struct rx_tasklet;
 	unsigned int vlan;		/* VLAN Id */
 	unsigned int chip_id;		/* PCI table chip id */
 	unsigned int rx_coalesce; 	/* Maximum frames each RxDMAComplete intr */
@@ -672,6 +681,9 @@ struct netdev_private {
 	struct netdev_desc *last_tx;	/* Last Tx descriptor used. */
 	unsigned long cur_rx, old_rx;	/* Producer/consumer ring indices */
 	unsigned long cur_tx, old_tx;
+	unsigned long cur_task;
+	atomic_t tx_desc_lock;
+	int budget;
 	struct timer_list timer;
 	int wake_polarity;
 	char name[256];		/* net device description */
@@ -708,4 +720,5 @@ MODULE_DEVICE_TABLE (pci, rio_pci_tbl);
 #define DEFAULT_RXT		750
 #define DEFAULT_TXC		1
 #define MAX_TXC			8
+#define RX_BUDGET		RX_RING_SIZE/2
 #endif				/* __DL2K_H__ */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/net/e1000/e1000_ethtool.c linux-2.4.29-pre3/drivers/net/e1000/e1000_ethtool.c
--- linux-2.4.28/drivers/net/e1000/e1000_ethtool.c	2004-12-22 16:17:16.793409704 +0000
+++ linux-2.4.29-pre3/drivers/net/e1000/e1000_ethtool.c	2004-12-22 16:07:10.405594664 +0000
@@ -249,7 +249,8 @@ e1000_set_pauseparam(struct net_device *
 			e1000_reset(adapter);
 	}
 	else
-		return e1000_force_mac_fc(hw);
+		return ((hw->media_type == e1000_media_type_fiber) ?
+			e1000_setup_link(hw) : e1000_force_mac_fc(hw));
 	
 	return 0;
 }
@@ -592,6 +593,9 @@ e1000_set_ringparam(struct net_device *n
 	tx_old = adapter->tx_ring;
 	rx_old = adapter->rx_ring;
 
+	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) 
+		return -EINVAL;
+
 	if(netif_running(adapter->netdev))
 		e1000_down(adapter);
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/net/e1000/e1000_hw.c linux-2.4.29-pre3/drivers/net/e1000/e1000_hw.c
--- linux-2.4.28/drivers/net/e1000/e1000_hw.c	2004-12-22 16:17:16.823405144 +0000
+++ linux-2.4.29-pre3/drivers/net/e1000/e1000_hw.c	2004-12-22 16:07:11.257465160 +0000
@@ -5227,31 +5227,6 @@ e1000_set_vco_speed(struct e1000_hw *hw)
     return E1000_SUCCESS;
 }
 
-/******************************************************************************
- * Verifies the hardware needs to allow ARPs to be processed by the host
- *
- * hw - Struct containing variables accessed by shared code
- *
- * returns: - TRUE/FALSE
- *
- *****************************************************************************/
-uint32_t
-e1000_enable_mng_pass_thru(struct e1000_hw *hw)
-{
-    uint32_t manc;
-
-    if (hw->asf_firmware_present) {
-        manc = E1000_READ_REG(hw, MANC);
-
-        if (!(manc & E1000_MANC_RCV_TCO_EN) ||
-            !(manc & E1000_MANC_EN_MAC_ADDR_FILTER))
-            return FALSE;
-        if ((manc & E1000_MANC_SMBUS_EN) && !(manc & E1000_MANC_ASF_EN))
-            return TRUE;
-    }
-    return FALSE;
-}
-
 static int32_t
 e1000_polarity_reversal_workaround(struct e1000_hw *hw)
 {
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/net/e1000/e1000_main.c linux-2.4.29-pre3/drivers/net/e1000/e1000_main.c
--- linux-2.4.28/drivers/net/e1000/e1000_main.c	2004-12-22 16:17:16.934388272 +0000
+++ linux-2.4.29-pre3/drivers/net/e1000/e1000_main.c	2004-12-22 16:06:31.117567352 +0000
@@ -48,7 +48,7 @@ char e1000_driver_string[] = "Intel(R) P
 #else
 #define DRIVERNAPI "-NAPI"
 #endif
-char e1000_driver_version[] = "5.4.11-k1"DRIVERNAPI;
+char e1000_driver_version[] = "5.5.4-k1"DRIVERNAPI;
 char e1000_copyright[] = "Copyright (c) 1999-2004 Intel Corporation.";
 
 /* e1000_pci_tbl - PCI Device ID Table
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/net/e1000/e1000_param.c linux-2.4.29-pre3/drivers/net/e1000/e1000_param.c
--- linux-2.4.28/drivers/net/e1000/e1000_param.c	2004-12-22 16:17:16.942387056 +0000
+++ linux-2.4.29-pre3/drivers/net/e1000/e1000_param.c	2004-12-22 16:05:48.778003944 +0000
@@ -211,7 +211,7 @@ E1000_PARAM(InterruptThrottleRate, "Inte
 #define MAX_TXABSDELAY            0xFFFF
 #define MIN_TXABSDELAY                 0
 
-#define DEFAULT_ITR                 8000 
+#define DEFAULT_ITR                 8000
 #define MAX_ITR                   100000
 #define MIN_ITR                      100
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/net/eexpress.c linux-2.4.29-pre3/drivers/net/eexpress.c
--- linux-2.4.28/drivers/net/eexpress.c	2003-08-25 11:44:42.000000000 +0000
+++ linux-2.4.29-pre3/drivers/net/eexpress.c	2004-12-22 16:05:31.125687504 +0000
@@ -7,7 +7,7 @@
  * Support for 8-bit mode by Zoltan Szilagyi <zoltans@cs.arizona.edu>
  *
  * Many modifications, and currently maintained, by
- *  Philip Blundell <Philip.Blundell@pobox.com>
+ *  Philip Blundell <philb@gnu.org>
  * Added the Compaq LTE  Alan Cox <alan@redhat.com>
  * Added MCA support Adam Fritzler <mid@auk.cx>
  *
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/net/forcedeth.c linux-2.4.29-pre3/drivers/net/forcedeth.c
--- linux-2.4.28/drivers/net/forcedeth.c	2004-04-14 13:05:30.000000000 +0000
+++ linux-2.4.29-pre3/drivers/net/forcedeth.c	2004-12-22 16:05:33.103386848 +0000
@@ -10,8 +10,11 @@
  * trademarks of NVIDIA Corporation in the United States and other
  * countries.
  *
- * Copyright (C) 2003 Manfred Spraul
+ * Copyright (C) 2003,4 Manfred Spraul
  * Copyright (C) 2004 Andrew de Quincey (wol support)
+ * Copyright (C) 2004 Carl-Daniel Hailfinger (invalid MAC handling, insane
+ *		IRQ rate fixes, bigendian fixes, cleanups, verification)
+ * Copyright (c) 2004 NVIDIA 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
@@ -60,15 +63,22 @@
  * 	0.19: 29 Nov 2003: Handle RxNoBuf, detect & handle invalid mac
  * 			   addresses, really stop rx if already running
  * 			   in nv_start_rx, clean up a bit.
- * 				(C) Carl-Daniel Hailfinger
  * 	0.20: 07 Dec 2003: alloc fixes
  * 	0.21: 12 Jan 2004: additional alloc fix, nic polling fix.
  *	0.22: 19 Jan 2004: reprogram timer to a sane rate, avoid lockup
- * 			   on close.
- * 				(C) Carl-Daniel Hailfinger, Manfred Spraul
+ *			   on close.
  *	0.23: 26 Jan 2004: various small cleanups
  *	0.24: 27 Feb 2004: make driver even less anonymous in backtraces
  *	0.25: 09 Mar 2004: wol support
+ *	0.26: 03 Jun 2004: netdriver specific annotation, sparse-related fixes
+ *	0.27: 19 Jun 2004: Gigabit support, new descriptor rings,
+ *			   added CK804/MCP04 device IDs, code fixes
+ *			   for registers, link status and other minor fixes.
+ *	0.28: 21 Jun 2004: Big cleanup, making driver mostly endian safe
+ *	0.29: 31 Aug 2004: Add backup timer for link change notification.
+ *	0.30: 25 Sep 2004: rx checksum support for nf 250 Gb. Add rx reset
+ *			   into nv_close, otherwise reenabling for wol can
+ *			   cause DMA to kfree'd memory.
  *
  * Known bugs:
  * We suspect that on some hardware no TX done interrupts are generated.
@@ -80,9 +90,11 @@
  * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
  * superfluous timer interrupts from the nic.
  */
-#define FORCEDETH_VERSION		"0.25"
+#define FORCEDETH_VERSION		"0.30"
+#define DRV_NAME			"forcedeth"
 
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
@@ -113,16 +125,18 @@
  * Hardware access:
  */
 
-#define DEV_NEED_LASTPACKET1	0x0001
-#define DEV_IRQMASK_1		0x0002
-#define DEV_IRQMASK_2		0x0004
-#define DEV_NEED_TIMERIRQ	0x0008
+#define DEV_NEED_LASTPACKET1	0x0001	/* set LASTPACKET1 in tx flags */
+#define DEV_IRQMASK_1		0x0002  /* use NVREG_IRQMASK_WANTED_1 for irq mask */
+#define DEV_IRQMASK_2		0x0004  /* use NVREG_IRQMASK_WANTED_2 for irq mask */
+#define DEV_NEED_TIMERIRQ	0x0008  /* set the timer irq flag in the irq mask */
+#define DEV_NEED_LINKTIMER	0x0010	/* poll link settings. Relies on the timer irq */
 
 enum {
 	NvRegIrqStatus = 0x000,
 #define NVREG_IRQSTAT_MIIEVENT	0x040
 #define NVREG_IRQSTAT_MASK		0x1ff
 	NvRegIrqMask = 0x004,
+#define NVREG_IRQ_RX_ERROR		0x0001
 #define NVREG_IRQ_RX			0x0002
 #define NVREG_IRQ_RX_NOBUF		0x0004
 #define NVREG_IRQ_TX_ERR		0x0008
@@ -132,7 +146,7 @@ enum {
 #define NVREG_IRQ_TX1			0x0100
 #define NVREG_IRQMASK_WANTED_1		0x005f
 #define NVREG_IRQMASK_WANTED_2		0x0147
-#define NVREG_IRQ_UNKNOWN		(~(NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_TX_ERR|NVREG_IRQ_TX2|NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_TX1))
+#define NVREG_IRQ_UNKNOWN		(~(NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_TX_ERR|NVREG_IRQ_TX2|NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_TX1))
 
 	NvRegUnknownSetupReg6 = 0x008,
 #define NVREG_UNKSETUP6_VAL		3
@@ -159,7 +173,7 @@ enum {
 
 	NvRegOffloadConfig = 0x90,
 #define NVREG_OFFLOAD_HOMEPHY	0x601
-#define NVREG_OFFLOAD_NORMAL	0x5ee
+#define NVREG_OFFLOAD_NORMAL	RX_NIC_BUFSIZE
 	NvRegReceiverControl = 0x094,
 #define NVREG_RCVCTL_START	0x01
 	NvRegReceiverStatus = 0x98,
@@ -168,6 +182,8 @@ enum {
 	NvRegRandomSeed = 0x9c,
 #define NVREG_RNDSEED_MASK	0x00ff
 #define NVREG_RNDSEED_FORCE	0x7f00
+#define NVREG_RNDSEED_FORCE2	0x2d00
+#define NVREG_RNDSEED_FORCE3	0x7400
 
 	NvRegUnknownSetupReg1 = 0xA0,
 #define NVREG_UNKSETUP1_VAL	0x16070f
@@ -181,6 +197,9 @@ enum {
 	NvRegMulticastMaskA = 0xB8,
 	NvRegMulticastMaskB = 0xBC,
 
+	NvRegPhyInterface = 0xC0,
+#define PHY_RGMII		0x10000000
+
 	NvRegTxRingPhysAddr = 0x100,
 	NvRegRxRingPhysAddr = 0x104,
 	NvRegRingSizes = 0x108,
@@ -189,12 +208,12 @@ enum {
 	NvRegUnknownTransmitterReg = 0x10c,
 	NvRegLinkSpeed = 0x110,
 #define NVREG_LINKSPEED_FORCE 0x10000
-#define NVREG_LINKSPEED_10	10
+#define NVREG_LINKSPEED_10	1000
 #define NVREG_LINKSPEED_100	100
-#define NVREG_LINKSPEED_1000	1000
+#define NVREG_LINKSPEED_1000	50
 	NvRegUnknownSetupReg5 = 0x130,
 #define NVREG_UNKSETUP5_BIT31	(1<<31)
-	NvRegUnknownSetupReg3 = 0x134,
+	NvRegUnknownSetupReg3 = 0x13c,
 #define NVREG_UNKSETUP3_VAL1	0x200010
 	NvRegTxRxControl = 0x144,
 #define NVREG_TXRXCTL_KICK	0x0001
@@ -202,6 +221,7 @@ enum {
 #define NVREG_TXRXCTL_BIT2	0x0004
 #define NVREG_TXRXCTL_IDLE	0x0008
 #define NVREG_TXRXCTL_RESET	0x0010
+#define NVREG_TXRXCTL_RXCHECK	0x0400
 	NvRegMIIStatus = 0x180,
 #define NVREG_MIISTAT_ERROR		0x0001
 #define NVREG_MIISTAT_LINKCHANGE	0x0008
@@ -213,15 +233,15 @@ enum {
 	NvRegAdapterControl = 0x188,
 #define NVREG_ADAPTCTL_START	0x02
 #define NVREG_ADAPTCTL_LINKUP	0x04
-#define NVREG_ADAPTCTL_PHYVALID	0x4000
+#define NVREG_ADAPTCTL_PHYVALID	0x40000
 #define NVREG_ADAPTCTL_RUNNING	0x100000
 #define NVREG_ADAPTCTL_PHYSHIFT	24
 	NvRegMIISpeed = 0x18c,
 #define NVREG_MIISPEED_BIT8	(1<<8)
 #define NVREG_MIIDELAY	5
 	NvRegMIIControl = 0x190,
-#define NVREG_MIICTL_INUSE	0x10000
-#define NVREG_MIICTL_WRITE	0x08000
+#define NVREG_MIICTL_INUSE	0x08000
+#define NVREG_MIICTL_WRITE	0x00400
 #define NVREG_MIICTL_ADDRSHIFT	5
 	NvRegMIIData = 0x194,
 	NvRegWakeUpFlags = 0x200,
@@ -253,34 +273,67 @@ enum {
 #define NVREG_POWERSTATE_D3		0x0003
 };
 
+/* Big endian: should work, but is untested */
 struct ring_desc {
 	u32 PacketBuffer;
-	u16 Length;
-	u16 Flags;
+	u32 FlagLen;
 };
 
-#define NV_TX_LASTPACKET	(1<<0)
-#define NV_TX_RETRYERROR	(1<<3)
-#define NV_TX_LASTPACKET1	(1<<8)
-#define NV_TX_DEFERRED		(1<<10)
-#define NV_TX_CARRIERLOST	(1<<11)
-#define NV_TX_LATECOLLISION	(1<<12)
-#define NV_TX_UNDERFLOW		(1<<13)
-#define NV_TX_ERROR		(1<<14)
-#define NV_TX_VALID		(1<<15)
-
-#define NV_RX_DESCRIPTORVALID	(1<<0)
-#define NV_RX_MISSEDFRAME	(1<<1)
-#define NV_RX_SUBSTRACT1	(1<<3)
-#define NV_RX_ERROR1		(1<<7)
-#define NV_RX_ERROR2		(1<<8)
-#define NV_RX_ERROR3		(1<<9)
-#define NV_RX_ERROR4		(1<<10)
-#define NV_RX_CRCERR		(1<<11)
-#define NV_RX_OVERFLOW		(1<<12)
-#define NV_RX_FRAMINGERR	(1<<13)
-#define NV_RX_ERROR		(1<<14)
-#define NV_RX_AVAIL		(1<<15)
+#define FLAG_MASK_V1 0xffff0000
+#define FLAG_MASK_V2 0xffffc000
+#define LEN_MASK_V1 (0xffffffff ^ FLAG_MASK_V1)
+#define LEN_MASK_V2 (0xffffffff ^ FLAG_MASK_V2)
+
+#define NV_TX_LASTPACKET	(1<<16)
+#define NV_TX_RETRYERROR	(1<<19)
+#define NV_TX_LASTPACKET1	(1<<24)
+#define NV_TX_DEFERRED		(1<<26)
+#define NV_TX_CARRIERLOST	(1<<27)
+#define NV_TX_LATECOLLISION	(1<<28)
+#define NV_TX_UNDERFLOW		(1<<29)
+#define NV_TX_ERROR		(1<<30)
+#define NV_TX_VALID		(1<<31)
+
+#define NV_TX2_LASTPACKET	(1<<29)
+#define NV_TX2_RETRYERROR	(1<<18)
+#define NV_TX2_LASTPACKET1	(1<<23)
+#define NV_TX2_DEFERRED		(1<<25)
+#define NV_TX2_CARRIERLOST	(1<<26)
+#define NV_TX2_LATECOLLISION	(1<<27)
+#define NV_TX2_UNDERFLOW	(1<<28)
+/* error and valid are the same for both */
+#define NV_TX2_ERROR		(1<<30)
+#define NV_TX2_VALID		(1<<31)
+
+#define NV_RX_DESCRIPTORVALID	(1<<16)
+#define NV_RX_MISSEDFRAME	(1<<17)
+#define NV_RX_SUBSTRACT1	(1<<18)
+#define NV_RX_ERROR1		(1<<23)
+#define NV_RX_ERROR2		(1<<24)
+#define NV_RX_ERROR3		(1<<25)
+#define NV_RX_ERROR4		(1<<26)
+#define NV_RX_CRCERR		(1<<27)
+#define NV_RX_OVERFLOW		(1<<28)
+#define NV_RX_FRAMINGERR	(1<<29)
+#define NV_RX_ERROR		(1<<30)
+#define NV_RX_AVAIL		(1<<31)
+
+#define NV_RX2_CHECKSUMMASK	(0x1C000000)
+#define NV_RX2_CHECKSUMOK1	(0x10000000)
+#define NV_RX2_CHECKSUMOK2	(0x14000000)
+#define NV_RX2_CHECKSUMOK3	(0x18000000)
+#define NV_RX2_DESCRIPTORVALID	(1<<29)
+#define NV_RX2_SUBSTRACT1	(1<<25)
+#define NV_RX2_ERROR1		(1<<18)
+#define NV_RX2_ERROR2		(1<<19)
+#define NV_RX2_ERROR3		(1<<20)
+#define NV_RX2_ERROR4		(1<<21)
+#define NV_RX2_CRCERR		(1<<22)
+#define NV_RX2_OVERFLOW		(1<<23)
+#define NV_RX2_FRAMINGERR	(1<<24)
+/* error and avail are the same for both */
+#define NV_RX2_ERROR		(1<<30)
+#define NV_RX2_AVAIL		(1<<31)
 
 /* Miscelaneous hardware related defines: */
 #define NV_PCI_REGSZ		0x270
@@ -306,28 +359,74 @@ struct ring_desc {
 
 /* General driver defaults */
 #define NV_WATCHDOG_TIMEO	(5*HZ)
-#define DEFAULT_MTU		1500	/* also maximum supported, at least for now */
 
 #define RX_RING		128
-#define TX_RING		16
-/* limited to 1 packet until we understand NV_TX_LASTPACKET */
-#define TX_LIMIT_STOP	10
-#define TX_LIMIT_START	5
+#define TX_RING		64
+/*
+ * If your nic mysteriously hangs then try to reduce the limits
+ * to 1/0: It might be required to set NV_TX_LASTPACKET in the
+ * last valid ring entry. But this would be impossible to
+ * implement - probably a disassembly error.
+ */
+#define TX_LIMIT_STOP	63
+#define TX_LIMIT_START	62
 
 /* rx/tx mac addr + type + vlan + align + slack*/
-#define RX_NIC_BUFSIZE		(DEFAULT_MTU + 64)
+#define RX_NIC_BUFSIZE		(ETH_DATA_LEN + 64)
 /* even more slack */
-#define RX_ALLOC_BUFSIZE	(DEFAULT_MTU + 128)
+#define RX_ALLOC_BUFSIZE	(ETH_DATA_LEN + 128)
 
 #define OOM_REFILL	(1+HZ/20)
 #define POLL_WAIT	(1+HZ/100)
+#define LINK_TIMEOUT	(3*HZ)
+
+/*
+ * desc_ver values:
+ * This field has two purposes:
+ * - Newer nics uses a different ring layout. The layout is selected by
+ *   comparing np->desc_ver with DESC_VER_xy.
+ * - It contains bits that are forced on when writing to NvRegTxRxControl.
+ */
+#define DESC_VER_1	0x0
+#define DESC_VER_2	(0x02100|NVREG_TXRXCTL_RXCHECK)
+
+/* PHY defines */
+#define PHY_OUI_MARVELL	0x5043
+#define PHY_OUI_CICADA	0x03f1
+#define PHYID1_OUI_MASK	0x03ff
+#define PHYID1_OUI_SHFT	6
+#define PHYID2_OUI_MASK	0xfc00
+#define PHYID2_OUI_SHFT	10
+#define PHY_INIT1	0x0f000
+#define PHY_INIT2	0x0e00
+#define PHY_INIT3	0x01000
+#define PHY_INIT4	0x0200
+#define PHY_INIT5	0x0004
+#define PHY_INIT6	0x02000
+#define PHY_GIGABIT	0x0100
+
+#define PHY_TIMEOUT	0x1
+#define PHY_ERROR	0x2
+
+#define PHY_100	0x1
+#define PHY_1000	0x2
+#define PHY_HALF	0x100
+
+/* FIXME: MII defines that should be added to <linux/mii.h> */
+#define MII_1000BT_CR	0x09
+#define MII_1000BT_SR	0x0a
+#define ADVERTISE_1000FULL	0x0200
+#define ADVERTISE_1000HALF	0x0100
+#define LPA_1000FULL	0x0800
+#define LPA_1000HALF	0x0400
+
 
 /*
  * SMP locking:
  * All hardware access under dev->priv->lock, except the performance
  * critical parts:
  * - rx is (pseudo-) lockless: it relies on the single-threading provided
- * 	by the arch code for interrupts.
+ *	by the arch code for interrupts.
  * - tx setup is lockless: it relies on dev->xmit_lock. Actual submission
  *	needs dev->priv->lock :-(
  * - set_multicast_list: preparation lockless, relies on dev->xmit_lock.
@@ -345,12 +444,15 @@ struct fe_priv {
 	int duplex;
 	int phyaddr;
 	int wolenabled;
+	unsigned int phy_oui;
+	u16 gigabit;
 
 	/* General data: RO fields */
 	dma_addr_t ring_addr;
 	struct pci_dev *pci_dev;
 	u32 orig_mac[2];
 	u32 irqmask;
+	u32 desc_ver;
 
 	/* rx specific fields.
 	 * Locking: Within irq hander or disable_irq+spin_lock(&np->lock);
@@ -363,6 +465,11 @@ struct fe_priv {
 	struct timer_list oom_kick;
 	struct timer_list nic_poll;
 
+	/* media detection workaround.
+	 * Locking: Within irq hander or disable_irq+spin_lock(&np->lock);
+	 */
+	int need_linktimer;
+	unsigned long link_timeout;
 	/*
 	 * tx specific fields.
 	 */
@@ -370,7 +477,7 @@ struct fe_priv {
 	unsigned int next_tx, nic_tx;
 	struct sk_buff *tx_skbuff[TX_RING];
 	dma_addr_t tx_dma[TX_RING];
-	u16 tx_flags;
+	u32 tx_flags;
 };
 
 /*
@@ -395,6 +502,12 @@ static inline void pci_push(u8 * base)
 	readl(base);
 }
 
+static inline u32 nv_descr_getlength(struct ring_desc *prd, u32 v)
+{
+	return le32_to_cpu(prd->FlagLen)
+		& ((v == DESC_VER_1) ? LEN_MASK_V1 : LEN_MASK_V2);
+}
+
 static int reg_delay(struct net_device *dev, int offset, u32 mask, u32 target,
 				int delay, int delaymax, const char *msg)
 {
@@ -421,24 +534,18 @@ static int reg_delay(struct net_device *
 static int mii_rw(struct net_device *dev, int addr, int miireg, int value)
 {
 	u8 *base = get_hwbase(dev);
-	int was_running;
 	u32 reg;
 	int retval;
 
 	writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus);
-	was_running = 0;
-	reg = readl(base + NvRegAdapterControl);
-	if (reg & NVREG_ADAPTCTL_RUNNING) {
-		was_running = 1;
-		writel(reg & ~NVREG_ADAPTCTL_RUNNING, base + NvRegAdapterControl);
-	}
+
 	reg = readl(base + NvRegMIIControl);
 	if (reg & NVREG_MIICTL_INUSE) {
 		writel(NVREG_MIICTL_INUSE, base + NvRegMIIControl);
 		udelay(NV_MIIBUSY_DELAY);
 	}
 
-	reg = NVREG_MIICTL_INUSE | (addr << NVREG_MIICTL_ADDRSHIFT) | miireg;
+	reg = (addr << NVREG_MIICTL_ADDRSHIFT) | miireg;
 	if (value != MII_READ) {
 		writel(value, base + NvRegMIIData);
 		reg |= NVREG_MIICTL_WRITE;
@@ -460,19 +567,117 @@ static int mii_rw(struct net_device *dev
 				dev->name, miireg, addr);
 		retval = -1;
 	} else {
-		/* FIXME: why is that required? */
-		udelay(50);
 		retval = readl(base + NvRegMIIData);
 		dprintk(KERN_DEBUG "%s: mii_rw read from reg %d at PHY %d: 0x%x.\n",
 				dev->name, miireg, addr, retval);
 	}
-	if (was_running) {
-		reg = readl(base + NvRegAdapterControl);
-		writel(reg | NVREG_ADAPTCTL_RUNNING, base + NvRegAdapterControl);
-	}
+
 	return retval;
 }
 
+static int phy_reset(struct net_device *dev)
+{
+	struct fe_priv *np = get_nvpriv(dev);
+	u32 miicontrol;
+	unsigned int tries = 0;
+
+	miicontrol = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ);
+	miicontrol |= BMCR_RESET;
+	if (mii_rw(dev, np->phyaddr, MII_BMCR, miicontrol)) {
+		return -1;
+	}
+
+	/* wait for 500ms */
+	msleep(500);
+
+	/* must wait till reset is deasserted */
+	while (miicontrol & BMCR_RESET) {
+		msleep(10);
+		miicontrol = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ);
+		/* FIXME: 100 tries seem excessive */
+		if (tries++ > 100)
+			return -1;
+	}
+	return 0;
+}
+
+static int phy_init(struct net_device *dev)
+{
+	struct fe_priv *np = get_nvpriv(dev);
+	u8 *base = get_hwbase(dev);
+	u32 phyinterface, phy_reserved, mii_status, mii_control, mii_control_1000,reg;
+
+	/* set advertise register */
+	reg = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ);
+	reg |= (ADVERTISE_10HALF|ADVERTISE_10FULL|ADVERTISE_100HALF|ADVERTISE_100FULL|0x800|0x400);
+	if (mii_rw(dev, np->phyaddr, MII_ADVERTISE, reg)) {
+		printk(KERN_INFO "%s: phy write to advertise failed.\n", pci_name(np->pci_dev));
+		return PHY_ERROR;
+	}
+
+	/* get phy interface type */
+	phyinterface = readl(base + NvRegPhyInterface);
+
+	/* see if gigabit phy */
+	mii_status = mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ);
+	if (mii_status & PHY_GIGABIT) {
+		np->gigabit = PHY_GIGABIT;
+		mii_control_1000 = mii_rw(dev, np->phyaddr, MII_1000BT_CR, MII_READ);
+		mii_control_1000 &= ~ADVERTISE_1000HALF;
+		if (phyinterface & PHY_RGMII)
+			mii_control_1000 |= ADVERTISE_1000FULL;
+		else
+			mii_control_1000 &= ~ADVERTISE_1000FULL;
+
+		if (mii_rw(dev, np->phyaddr, MII_1000BT_CR, mii_control_1000)) {
+			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+			return PHY_ERROR;
+		}
+	}
+	else
+		np->gigabit = 0;
+
+	/* reset the phy */
+	if (phy_reset(dev)) {
+		printk(KERN_INFO "%s: phy reset failed\n", pci_name(np->pci_dev));
+		return PHY_ERROR;
+	}
+
+	/* phy vendor specific configuration */
+	if ((np->phy_oui == PHY_OUI_CICADA) && (phyinterface & PHY_RGMII) ) {
+		phy_reserved = mii_rw(dev, np->phyaddr, MII_RESV1, MII_READ);
+		phy_reserved &= ~(PHY_INIT1 | PHY_INIT2);
+		phy_reserved |= (PHY_INIT3 | PHY_INIT4);
+		if (mii_rw(dev, np->phyaddr, MII_RESV1, phy_reserved)) {
+			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+			return PHY_ERROR;
+		}
+		phy_reserved = mii_rw(dev, np->phyaddr, MII_NCONFIG, MII_READ);
+		phy_reserved |= PHY_INIT5;
+		if (mii_rw(dev, np->phyaddr, MII_NCONFIG, phy_reserved)) {
+			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+			return PHY_ERROR;
+		}
+	}
+	if (np->phy_oui == PHY_OUI_CICADA) {
+		phy_reserved = mii_rw(dev, np->phyaddr, MII_SREVISION, MII_READ);
+		phy_reserved |= PHY_INIT6;
+		if (mii_rw(dev, np->phyaddr, MII_SREVISION, phy_reserved)) {
+			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+			return PHY_ERROR;
+		}
+	}
+
+	/* restart auto negotiation */
+	mii_control = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ);
+	mii_control |= (BMCR_ANRESTART | BMCR_ANENABLE);
+	if (mii_rw(dev, np->phyaddr, MII_BMCR, mii_control)) {
+		return PHY_ERROR;
+	}
+
+	return 0;
+}
+
 static void nv_start_rx(struct net_device *dev)
 {
 	struct fe_priv *np = get_nvpriv(dev);
@@ -487,6 +692,8 @@ static void nv_start_rx(struct net_devic
 	writel(np->linkspeed, base + NvRegLinkSpeed);
 	pci_push(base);
 	writel(NVREG_RCVCTL_START, base + NvRegReceiverControl);
+	dprintk(KERN_DEBUG "%s: nv_start_rx to duplex %d, speed 0x%08x.\n",
+				dev->name, np->duplex, np->linkspeed);
 	pci_push(base);
 }
 
@@ -497,8 +704,8 @@ static void nv_stop_rx(struct net_device
 	dprintk(KERN_DEBUG "%s: nv_stop_rx\n", dev->name);
 	writel(0, base + NvRegReceiverControl);
 	reg_delay(dev, NvRegReceiverStatus, NVREG_RCVSTAT_BUSY, 0,
-		       NV_RXSTOP_DELAY1, NV_RXSTOP_DELAY1MAX,
-		       KERN_INFO "nv_stop_rx: ReceiverStatus remained busy");
+			NV_RXSTOP_DELAY1, NV_RXSTOP_DELAY1MAX,
+			KERN_INFO "nv_stop_rx: ReceiverStatus remained busy");
 
 	udelay(NV_RXSTOP_DELAY2);
 	writel(0, base + NvRegLinkSpeed);
@@ -520,8 +727,8 @@ static void nv_stop_tx(struct net_device
 	dprintk(KERN_DEBUG "%s: nv_stop_tx\n", dev->name);
 	writel(0, base + NvRegTransmitterControl);
 	reg_delay(dev, NvRegTransmitterStatus, NVREG_XMITSTAT_BUSY, 0,
-		       NV_TXSTOP_DELAY1, NV_TXSTOP_DELAY1MAX,
-		       KERN_INFO "nv_stop_tx: TransmitterStatus remained busy");
+			NV_TXSTOP_DELAY1, NV_TXSTOP_DELAY1MAX,
+			KERN_INFO "nv_stop_tx: TransmitterStatus remained busy");
 
 	udelay(NV_TXSTOP_DELAY2);
 	writel(0, base + NvRegUnknownTransmitterReg);
@@ -529,13 +736,14 @@ static void nv_stop_tx(struct net_device
 
 static void nv_txrx_reset(struct net_device *dev)
 {
+	struct fe_priv *np = get_nvpriv(dev);
 	u8 *base = get_hwbase(dev);
 
 	dprintk(KERN_DEBUG "%s: nv_txrx_reset\n", dev->name);
-	writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET, base + NvRegTxRxControl);
+	writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->desc_ver, base + NvRegTxRxControl);
 	pci_push(base);
 	udelay(NV_TXRX_RESET_DELAY);
-	writel(NVREG_TXRXCTL_BIT2, base + NvRegTxRxControl);
+	writel(NVREG_TXRXCTL_BIT2 | np->desc_ver, base + NvRegTxRxControl);
 	pci_push(base);
 }
 
@@ -556,91 +764,50 @@ static struct net_device_stats *nv_get_s
 	return &np->stats;
 }
 
-static int nv_ethtool_ioctl(struct net_device *dev, void *useraddr)
+static void nv_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
 	struct fe_priv *np = get_nvpriv(dev);
-	u8 *base = get_hwbase(dev);
-	u32 ethcmd;
-
-	if (copy_from_user(&ethcmd, useraddr, sizeof (ethcmd)))
-		return -EFAULT;
-
-	switch (ethcmd) {
-	case ETHTOOL_GDRVINFO:
-	{
-		struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
-		strcpy(info.driver, "forcedeth");
-		strcpy(info.version, FORCEDETH_VERSION);
-		strcpy(info.bus_info, pci_name(np->pci_dev));
-		if (copy_to_user(useraddr, &info, sizeof (info)))
-			return -EFAULT;
-		return 0;
-	}
-	case ETHTOOL_GLINK:
-	{
-		struct ethtool_value edata = { ETHTOOL_GLINK };
-
-		edata.data = !!netif_carrier_ok(dev);
-
-		if (copy_to_user(useraddr, &edata, sizeof(edata)))
-			return -EFAULT;
-		return 0;
-	}
-	case ETHTOOL_GWOL:
-	{
-		struct ethtool_wolinfo wolinfo;
-		memset(&wolinfo, 0, sizeof(wolinfo));
-		wolinfo.supported = WAKE_MAGIC;
-
-		spin_lock_irq(&np->lock);
-		if (np->wolenabled)
-			wolinfo.wolopts = WAKE_MAGIC;
-		spin_unlock_irq(&np->lock);
-
-		if (copy_to_user(useraddr, &wolinfo, sizeof(wolinfo)))
-			return -EFAULT;
-		return 0;
-	}
-	case ETHTOOL_SWOL:
-	{
-		struct ethtool_wolinfo wolinfo;
-		if (copy_from_user(&wolinfo, useraddr, sizeof(wolinfo)))
-			return -EFAULT;
-
-		spin_lock_irq(&np->lock);
-		if (wolinfo.wolopts == 0) {
-			writel(0, base + NvRegWakeUpFlags);
-			np->wolenabled = 0;
-		}
-		if (wolinfo.wolopts & WAKE_MAGIC) {
-			writel(NVREG_WAKEUPFLAGS_ENABLE, base + NvRegWakeUpFlags);
-			np->wolenabled = 1;
-		}
-		spin_unlock_irq(&np->lock);
-		return 0;
-	}
+	strcpy(info->driver, "forcedeth");
+	strcpy(info->version, FORCEDETH_VERSION);
+	strcpy(info->bus_info, pci_name(np->pci_dev));
+}
 
-	default:
-		break;
-	}
+static void nv_get_wol(struct net_device *dev, struct ethtool_wolinfo *wolinfo)
+{
+	struct fe_priv *np = get_nvpriv(dev);
+	wolinfo->supported = WAKE_MAGIC;
 
-	return -EOPNOTSUPP;
+	spin_lock_irq(&np->lock);
+	if (np->wolenabled)
+		wolinfo->wolopts = WAKE_MAGIC;
+	spin_unlock_irq(&np->lock);
 }
-/*
- * nv_ioctl: dev->do_ioctl function
- * Called with rtnl_lock held.
- */
-static int nv_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+
+static int nv_set_wol(struct net_device *dev, struct ethtool_wolinfo *wolinfo)
 {
-	switch(cmd) {
-	case SIOCETHTOOL:
-		return nv_ethtool_ioctl(dev, (void *) rq->ifr_data);
+	struct fe_priv *np = get_nvpriv(dev);
+	u8 *base = get_hwbase(dev);
 
-	default:
-		return -EOPNOTSUPP;
+	spin_lock_irq(&np->lock);
+	if (wolinfo->wolopts == 0) {
+		writel(0, base + NvRegWakeUpFlags);
+		np->wolenabled = 0;
+	}
+	if (wolinfo->wolopts & WAKE_MAGIC) {
+		writel(NVREG_WAKEUPFLAGS_ENABLE, base + NvRegWakeUpFlags);
+		np->wolenabled = 1;
 	}
+	spin_unlock_irq(&np->lock);
+	return 0;
 }
 
+static struct ethtool_ops ops = {
+	.get_drvinfo = nv_get_drvinfo,
+	.get_link = ethtool_op_get_link,
+	.get_wol = nv_get_wol,
+	.set_wol = nv_set_wol,
+};
+
 /*
  * nv_alloc_rx: fill rx ring entries.
  * Return 1 if the allocations for the skbs failed and the
@@ -650,11 +817,12 @@ static int nv_alloc_rx(struct net_device
 {
 	struct fe_priv *np = get_nvpriv(dev);
 	unsigned int refill_rx = np->refill_rx;
+	int nr;
 
 	while (np->cur_rx != refill_rx) {
-		int nr = refill_rx % RX_RING;
 		struct sk_buff *skb;
 
+		nr = refill_rx % RX_RING;
 		if (np->rx_skbuff[nr] == NULL) {
 
 			skb = dev_alloc_skb(RX_ALLOC_BUFSIZE);
@@ -669,10 +837,9 @@ static int nv_alloc_rx(struct net_device
 		np->rx_dma[nr] = pci_map_single(np->pci_dev, skb->data, skb->len,
 						PCI_DMA_FROMDEVICE);
 		np->rx_ring[nr].PacketBuffer = cpu_to_le32(np->rx_dma[nr]);
-		np->rx_ring[nr].Length = cpu_to_le16(RX_NIC_BUFSIZE);
 		wmb();
-		np->rx_ring[nr].Flags = cpu_to_le16(NV_RX_AVAIL);
-		dprintk(KERN_DEBUG "%s: nv_alloc_rx: Packet  %d marked as Available\n",
+		np->rx_ring[nr].FlagLen = cpu_to_le32(RX_NIC_BUFSIZE | NV_RX_AVAIL);
+		dprintk(KERN_DEBUG "%s: nv_alloc_rx: Packet %d marked as Available\n",
 					dev->name, refill_rx);
 		refill_rx++;
 	}
@@ -703,15 +870,13 @@ static int nv_init_ring(struct net_devic
 	int i;
 
 	np->next_tx = np->nic_tx = 0;
-	for (i = 0; i < TX_RING; i++) {
-		np->tx_ring[i].Flags = 0;
-	}
+	for (i = 0; i < TX_RING; i++)
+		np->tx_ring[i].FlagLen = 0;
 
 	np->cur_rx = RX_RING;
 	np->refill_rx = 0;
-	for (i = 0; i < RX_RING; i++) {
-		np->rx_ring[i].Flags = 0;
-	}
+	for (i = 0; i < RX_RING; i++)
+		np->rx_ring[i].FlagLen = 0;
 	return nv_alloc_rx(dev);
 }
 
@@ -720,7 +885,7 @@ static void nv_drain_tx(struct net_devic
 	struct fe_priv *np = get_nvpriv(dev);
 	int i;
 	for (i = 0; i < TX_RING; i++) {
-		np->tx_ring[i].Flags = 0;
+		np->tx_ring[i].FlagLen = 0;
 		if (np->tx_skbuff[i]) {
 			pci_unmap_single(np->pci_dev, np->tx_dma[i],
 						np->tx_skbuff[i]->len,
@@ -737,7 +902,7 @@ static void nv_drain_rx(struct net_devic
 	struct fe_priv *np = get_nvpriv(dev);
 	int i;
 	for (i = 0; i < RX_RING; i++) {
-		np->rx_ring[i].Flags = 0;
+		np->rx_ring[i].FlagLen = 0;
 		wmb();
 		if (np->rx_skbuff[i]) {
 			pci_unmap_single(np->pci_dev, np->rx_dma[i],
@@ -769,11 +934,10 @@ static int nv_start_xmit(struct sk_buff 
 					PCI_DMA_TODEVICE);
 
 	np->tx_ring[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]);
-	np->tx_ring[nr].Length = cpu_to_le16(skb->len-1);
 
 	spin_lock_irq(&np->lock);
 	wmb();
-	np->tx_ring[nr].Flags = np->tx_flags;
+	np->tx_ring[nr].FlagLen = cpu_to_le32( (skb->len-1) | np->tx_flags );
 	dprintk(KERN_DEBUG "%s: nv_start_xmit: packet packet %d queued for transmission.\n",
 				dev->name, np->next_tx);
 	{
@@ -792,7 +956,7 @@ static int nv_start_xmit(struct sk_buff 
 	if (np->next_tx - np->nic_tx >= TX_LIMIT_STOP)
 		netif_stop_queue(dev);
 	spin_unlock_irq(&np->lock);
-	writel(NVREG_TXRXCTL_KICK, get_hwbase(dev) + NvRegTxRxControl);
+	writel(NVREG_TXRXCTL_KICK|np->desc_ver, get_hwbase(dev) + NvRegTxRxControl);
 	pci_push(get_hwbase(dev));
 	return 0;
 }
@@ -805,27 +969,42 @@ static int nv_start_xmit(struct sk_buff 
 static void nv_tx_done(struct net_device *dev)
 {
 	struct fe_priv *np = get_nvpriv(dev);
+	u32 Flags;
+	int i;
 
-	while (np->nic_tx < np->next_tx) {
-		struct ring_desc *prd;
-		int i = np->nic_tx % TX_RING;
+	while (np->nic_tx != np->next_tx) {
+		i = np->nic_tx % TX_RING;
 
-		prd = &np->tx_ring[i];
+		Flags = le32_to_cpu(np->tx_ring[i].FlagLen);
 
 		dprintk(KERN_DEBUG "%s: nv_tx_done: looking at packet %d, Flags 0x%x.\n",
-					dev->name, np->nic_tx, prd->Flags);
-		if (prd->Flags & cpu_to_le16(NV_TX_VALID))
+					dev->name, np->nic_tx, Flags);
+		if (Flags & NV_TX_VALID)
 			break;
-		if (prd->Flags & cpu_to_le16(NV_TX_RETRYERROR|NV_TX_CARRIERLOST|NV_TX_LATECOLLISION|
-						NV_TX_UNDERFLOW|NV_TX_ERROR)) {
-			if (prd->Flags & cpu_to_le16(NV_TX_UNDERFLOW))
-				np->stats.tx_fifo_errors++;
-			if (prd->Flags & cpu_to_le16(NV_TX_CARRIERLOST))
-				np->stats.tx_carrier_errors++;
-			np->stats.tx_errors++;
+		if (np->desc_ver == DESC_VER_1) {
+			if (Flags & (NV_TX_RETRYERROR|NV_TX_CARRIERLOST|NV_TX_LATECOLLISION|
+							NV_TX_UNDERFLOW|NV_TX_ERROR)) {
+				if (Flags & NV_TX_UNDERFLOW)
+					np->stats.tx_fifo_errors++;
+				if (Flags & NV_TX_CARRIERLOST)
+					np->stats.tx_carrier_errors++;
+				np->stats.tx_errors++;
+			} else {
+				np->stats.tx_packets++;
+				np->stats.tx_bytes += np->tx_skbuff[i]->len;
+			}
 		} else {
-			np->stats.tx_packets++;
-			np->stats.tx_bytes += np->tx_skbuff[i]->len;
+			if (Flags & (NV_TX2_RETRYERROR|NV_TX2_CARRIERLOST|NV_TX2_LATECOLLISION|
+							NV_TX2_UNDERFLOW|NV_TX2_ERROR)) {
+				if (Flags & NV_TX2_UNDERFLOW)
+					np->stats.tx_fifo_errors++;
+				if (Flags & NV_TX2_CARRIERLOST)
+					np->stats.tx_carrier_errors++;
+				np->stats.tx_errors++;
+			} else {
+				np->stats.tx_packets++;
+				np->stats.tx_bytes += np->tx_skbuff[i]->len;
+			}
 		}
 		pci_unmap_single(np->pci_dev, np->tx_dma[i],
 					np->tx_skbuff[i]->len,
@@ -875,9 +1054,9 @@ static void nv_tx_timeout(struct net_dev
 static void nv_rx_process(struct net_device *dev)
 {
 	struct fe_priv *np = get_nvpriv(dev);
+	u32 Flags;
 
 	for (;;) {
-		struct ring_desc *prd;
 		struct sk_buff *skb;
 		int len;
 		int i;
@@ -885,11 +1064,13 @@ static void nv_rx_process(struct net_dev
 			break;	/* we scanned the whole ring - do not continue */
 
 		i = np->cur_rx % RX_RING;
-		prd = &np->rx_ring[i];
+		Flags = le32_to_cpu(np->rx_ring[i].FlagLen);
+		len = nv_descr_getlength(&np->rx_ring[i], np->desc_ver);
+
 		dprintk(KERN_DEBUG "%s: nv_rx_process: looking at packet %d, Flags 0x%x.\n",
-					dev->name, np->cur_rx, prd->Flags);
+					dev->name, np->cur_rx, Flags);
 
-		if (prd->Flags & cpu_to_le16(NV_RX_AVAIL))
+		if (Flags & NV_RX_AVAIL)
 			break;	/* still owned by hardware, */
 
 		/*
@@ -903,7 +1084,7 @@ static void nv_rx_process(struct net_dev
 
 		{
 			int j;
-			dprintk(KERN_DEBUG "Dumping packet (flags 0x%x).",prd->Flags);
+			dprintk(KERN_DEBUG "Dumping packet (flags 0x%x).",Flags);
 			for (j=0; j<64; j++) {
 				if ((j%16) == 0)
 					dprintk("\n%03x:", j);
@@ -912,41 +1093,78 @@ static void nv_rx_process(struct net_dev
 			dprintk("\n");
 		}
 		/* look at what we actually got: */
-		if (!(prd->Flags & cpu_to_le16(NV_RX_DESCRIPTORVALID)))
-			goto next_pkt;
-
-
-		len = le16_to_cpu(prd->Length);
+		if (np->desc_ver == DESC_VER_1) {
+			if (!(Flags & NV_RX_DESCRIPTORVALID))
+				goto next_pkt;
 
-		if (prd->Flags & cpu_to_le16(NV_RX_MISSEDFRAME)) {
-			np->stats.rx_missed_errors++;
-			np->stats.rx_errors++;
-			goto next_pkt;
-		}
-		if (prd->Flags & cpu_to_le16(NV_RX_ERROR1|NV_RX_ERROR2|NV_RX_ERROR3|NV_RX_ERROR4)) {
-			np->stats.rx_errors++;
-			goto next_pkt;
-		}
-		if (prd->Flags & cpu_to_le16(NV_RX_CRCERR)) {
-			np->stats.rx_crc_errors++;
-			np->stats.rx_errors++;
-			goto next_pkt;
-		}
-		if (prd->Flags & cpu_to_le16(NV_RX_OVERFLOW)) {
-			np->stats.rx_over_errors++;
-			np->stats.rx_errors++;
-			goto next_pkt;
-		}
-		if (prd->Flags & cpu_to_le16(NV_RX_ERROR)) {
-			/* framing errors are soft errors, the rest is fatal. */
-			if (prd->Flags & cpu_to_le16(NV_RX_FRAMINGERR)) {
-				if (prd->Flags & cpu_to_le16(NV_RX_SUBSTRACT1)) {
-					len--;
+			if (Flags & NV_RX_MISSEDFRAME) {
+				np->stats.rx_missed_errors++;
+				np->stats.rx_errors++;
+				goto next_pkt;
+			}
+			if (Flags & (NV_RX_ERROR1|NV_RX_ERROR2|NV_RX_ERROR3|NV_RX_ERROR4)) {
+				np->stats.rx_errors++;
+				goto next_pkt;
+			}
+			if (Flags & NV_RX_CRCERR) {
+				np->stats.rx_crc_errors++;
+				np->stats.rx_errors++;
+				goto next_pkt;
+			}
+			if (Flags & NV_RX_OVERFLOW) {
+				np->stats.rx_over_errors++;
+				np->stats.rx_errors++;
+				goto next_pkt;
+			}
+			if (Flags & NV_RX_ERROR) {
+				/* framing errors are soft errors, the rest is fatal. */
+				if (Flags & NV_RX_FRAMINGERR) {
+					if (Flags & NV_RX_SUBSTRACT1) {
+						len--;
+					}
+				} else {
+					np->stats.rx_errors++;
+					goto next_pkt;
 				}
-			} else {
+			}
+		} else {
+			if (!(Flags & NV_RX2_DESCRIPTORVALID))
+				goto next_pkt;
+
+			if (Flags & (NV_RX2_ERROR1|NV_RX2_ERROR2|NV_RX2_ERROR3|NV_RX2_ERROR4)) {
 				np->stats.rx_errors++;
 				goto next_pkt;
 			}
+			if (Flags & NV_RX2_CRCERR) {
+				np->stats.rx_crc_errors++;
+				np->stats.rx_errors++;
+				goto next_pkt;
+			}
+			if (Flags & NV_RX2_OVERFLOW) {
+				np->stats.rx_over_errors++;
+				np->stats.rx_errors++;
+				goto next_pkt;
+			}
+			if (Flags & NV_RX2_ERROR) {
+				/* framing errors are soft errors, the rest is fatal. */
+				if (Flags & NV_RX2_FRAMINGERR) {
+					if (Flags & NV_RX2_SUBSTRACT1) {
+						len--;
+					}
+				} else {
+					np->stats.rx_errors++;
+					goto next_pkt;
+				}
+			}
+			Flags &= NV_RX2_CHECKSUMMASK;
+			if (Flags == NV_RX2_CHECKSUMOK1 ||
+					Flags == NV_RX2_CHECKSUMOK2 ||
+					Flags == NV_RX2_CHECKSUMOK3) {
+				dprintk(KERN_DEBUG "%s: hw checksum hit!.\n", dev->name);
+				np->rx_skbuff[i]->ip_summed = CHECKSUM_UNNECESSARY;
+			} else {
+				dprintk(KERN_DEBUG "%s: hwchecksum miss!.\n", dev->name);
+			}
 		}
 		/* got a valid packet - forward it to the network core */
 		skb = np->rx_skbuff[i];
@@ -971,7 +1189,7 @@ next_pkt:
  */
 static int nv_change_mtu(struct net_device *dev, int new_mtu)
 {
-	if (new_mtu > DEFAULT_MTU)
+	if (new_mtu > ETH_DATA_LEN)
 		return -EINVAL;
 	dev->mtu = new_mtu;
 	return 0;
@@ -1035,6 +1253,8 @@ static void nv_set_multicast(struct net_
 	writel(mask[0], base + NvRegMulticastMaskA);
 	writel(mask[1], base + NvRegMulticastMaskB);
 	writel(pff, base + NvRegPacketFilterFlags);
+	dprintk(KERN_INFO "%s: reconfiguration for multicast lists.\n",
+		dev->name);
 	nv_start_rx(dev);
 	spin_unlock_irq(&np->lock);
 }
@@ -1042,16 +1262,62 @@ static void nv_set_multicast(struct net_
 static int nv_update_linkspeed(struct net_device *dev)
 {
 	struct fe_priv *np = get_nvpriv(dev);
-	int adv, lpa, newls, newdup;
+	u8 *base = get_hwbase(dev);
+	int adv, lpa;
+	int newls = np->linkspeed;
+	int newdup = np->duplex;
+	int mii_status;
+	int retval = 0;
+	u32 control_1000, status_1000, phyreg;
+
+	/* BMSR_LSTATUS is latched, read it twice:
+	 * we want the current value.
+	 */
+	mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ);
+	mii_status = mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ);
+
+	if (!(mii_status & BMSR_LSTATUS)) {
+		dprintk(KERN_DEBUG "%s: no link detected by phy - falling back to 10HD.\n",
+				dev->name);
+		newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10;
+		newdup = 0;
+		retval = 0;
+		goto set_speed;
+	}
+
+	/* check auto negotiation is complete */
+	if (!(mii_status & BMSR_ANEGCOMPLETE)) {
+		/* still in autonegotiation - configure nic for 10 MBit HD and wait. */
+		newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10;
+		newdup = 0;
+		retval = 0;
+		dprintk(KERN_DEBUG "%s: autoneg not completed - falling back to 10HD.\n", dev->name);
+		goto set_speed;
+	}
+
+	retval = 1;
+	if (np->gigabit == PHY_GIGABIT) {
+		control_1000 = mii_rw(dev, np->phyaddr, MII_1000BT_CR, MII_READ);
+		status_1000 = mii_rw(dev, np->phyaddr, MII_1000BT_SR, MII_READ);
+
+		if ((control_1000 & ADVERTISE_1000FULL) &&
+			(status_1000 & LPA_1000FULL)) {
+		dprintk(KERN_DEBUG "%s: nv_update_linkspeed: GBit ethernet detected.\n",
+				dev->name);
+			newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_1000;
+			newdup = 1;
+			goto set_speed;
+		}
+	}
 
 	adv = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ);
 	lpa = mii_rw(dev, np->phyaddr, MII_LPA, MII_READ);
 	dprintk(KERN_DEBUG "%s: nv_update_linkspeed: PHY advertises 0x%04x, lpa 0x%04x.\n",
 				dev->name, adv, lpa);
 
-	/* FIXME: handle parallel detection properly, handle gigabit ethernet */
+	/* FIXME: handle parallel detection properly */
 	lpa = lpa & adv;
-	if (lpa  & LPA_100FULL) {
+	if (lpa & LPA_100FULL) {
 		newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_100;
 		newdup = 1;
 	} else if (lpa & LPA_100HALF) {
@@ -1068,37 +1334,57 @@ static int nv_update_linkspeed(struct ne
 		newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10;
 		newdup = 0;
 	}
-	if (np->duplex != newdup || np->linkspeed != newls) {
-		np->duplex = newdup;
-		np->linkspeed = newls;
-		return 1;
-	}
-	return 0;
-}
 
-static void nv_link_irq(struct net_device *dev)
-{
-	struct fe_priv *np = get_nvpriv(dev);
-	u8 *base = get_hwbase(dev);
-	u32 miistat;
-	int miival;
+set_speed:
+	if (np->duplex == newdup && np->linkspeed == newls)
+		return retval;
+
+	dprintk(KERN_INFO "%s: changing link setting from %d/%d to %d/%d.\n",
+			dev->name, np->linkspeed, np->duplex, newls, newdup);
+
+	np->duplex = newdup;
+	np->linkspeed = newls;
+
+	if (np->gigabit == PHY_GIGABIT) {
+		phyreg = readl(base + NvRegRandomSeed);
+		phyreg &= ~(0x3FF00);
+		if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_10)
+			phyreg |= NVREG_RNDSEED_FORCE3;
+		else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_100)
+			phyreg |= NVREG_RNDSEED_FORCE2;
+		else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_1000)
+			phyreg |= NVREG_RNDSEED_FORCE;
+		writel(phyreg, base + NvRegRandomSeed);
+	}
+
+	phyreg = readl(base + NvRegPhyInterface);
+	phyreg &= ~(PHY_HALF|PHY_100|PHY_1000);
+	if (np->duplex == 0)
+		phyreg |= PHY_HALF;
+	if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_100)
+		phyreg |= PHY_100;
+	else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_1000)
+		phyreg |= PHY_1000;
+	writel(phyreg, base + NvRegPhyInterface);
 
-	miistat = readl(base + NvRegMIIStatus);
-	writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus);
-	printk(KERN_DEBUG "%s: link change notification, status 0x%x.\n", dev->name, miistat);
+	writel(NVREG_MISC1_FORCE | ( np->duplex ? 0 : NVREG_MISC1_HD),
+		base + NvRegMisc1);
+	pci_push(base);
+	writel(np->linkspeed, base + NvRegLinkSpeed);
+	pci_push(base);
 
-	miival = mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ);
-	if (miival & BMSR_ANEGCOMPLETE) {
-		nv_update_linkspeed(dev);
+	return retval;
+}
 
+static void nv_linkchange(struct net_device *dev)
+{
+	if (nv_update_linkspeed(dev)) {
 		if (netif_carrier_ok(dev)) {
 			nv_stop_rx(dev);
 		} else {
 			netif_carrier_on(dev);
 			printk(KERN_INFO "%s: link up.\n", dev->name);
 		}
-		writel(NVREG_MISC1_FORCE | ( np->duplex ? 0 : NVREG_MISC1_HD),
-					base + NvRegMisc1);
 		nv_start_rx(dev);
 	} else {
 		if (netif_carrier_ok(dev)) {
@@ -1106,11 +1392,23 @@ static void nv_link_irq(struct net_devic
 			printk(KERN_INFO "%s: link down.\n", dev->name);
 			nv_stop_rx(dev);
 		}
-		writel(np->linkspeed, base + NvRegLinkSpeed);
-		pci_push(base);
 	}
 }
 
+static void nv_link_irq(struct net_device *dev)
+{
+	u8 *base = get_hwbase(dev);
+	u32 miistat;
+
+	miistat = readl(base + NvRegMIIStatus);
+	writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus);
+	dprintk(KERN_INFO "%s: link change irq, status 0x%x.\n", dev->name, miistat);
+
+	if (miistat & (NVREG_MIISTAT_LINKCHANGE))
+		nv_linkchange(dev);
+	dprintk(KERN_DEBUG "%s: link change notification done.\n", dev->name);
+}
+
 static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs)
 {
 	struct net_device *dev = (struct net_device *) data;
@@ -1135,7 +1433,7 @@ static irqreturn_t nv_nic_irq(int foo, v
 			spin_unlock(&np->lock);
 		}
 
-		if (events & (NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF)) {
+		if (events & (NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF)) {
 			nv_rx_process(dev);
 			if (nv_alloc_rx(dev)) {
 				spin_lock(&np->lock);
@@ -1150,6 +1448,12 @@ static irqreturn_t nv_nic_irq(int foo, v
 			nv_link_irq(dev);
 			spin_unlock(&np->lock);
 		}
+		if (np->need_linktimer && time_after(jiffies, np->link_timeout)) {
+			spin_lock(&np->lock);
+			nv_linkchange(dev);
+			spin_unlock(&np->lock);
+			np->link_timeout = jiffies + LINK_TIMEOUT;
+		}
 		if (events & (NVREG_IRQ_TX_ERR)) {
 			dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n",
 						dev->name, events);
@@ -1157,7 +1461,7 @@ static irqreturn_t nv_nic_irq(int foo, v
 		if (events & (NVREG_IRQ_UNKNOWN)) {
 			printk(KERN_DEBUG "%s: received irq with unknown events 0x%x. Please report\n",
 						dev->name, events);
- 		}
+		}
 		if (i > max_interrupt_work) {
 			spin_lock(&np->lock);
 			/* disable interrupts on the nic */
@@ -1210,21 +1514,27 @@ static int nv_open(struct net_device *de
 	writel(0, base + NvRegMulticastMaskA);
 	writel(0, base + NvRegMulticastMaskB);
 	writel(0, base + NvRegPacketFilterFlags);
+
+	writel(0, base + NvRegTransmitterControl);
+	writel(0, base + NvRegReceiverControl);
+
 	writel(0, base + NvRegAdapterControl);
+
+	/* 2) initialize descriptor rings */
+	oom = nv_init_ring(dev);
+
 	writel(0, base + NvRegLinkSpeed);
 	writel(0, base + NvRegUnknownTransmitterReg);
 	nv_txrx_reset(dev);
 	writel(0, base + NvRegUnknownSetupReg6);
 
-	/* 2) initialize descriptor rings */
 	np->in_shutdown = 0;
-	oom = nv_init_ring(dev);
 
 	/* 3) set mac address */
 	{
 		u32 mac[2];
 
-		mac[0] = (dev->dev_addr[0] <<  0) + (dev->dev_addr[1] <<  8) +
+		mac[0] = (dev->dev_addr[0] << 0) + (dev->dev_addr[1] << 8) +
 				(dev->dev_addr[2] << 16) + (dev->dev_addr[3] << 24);
 		mac[1] = (dev->dev_addr[4] << 0) + (dev->dev_addr[5] << 8);
 
@@ -1232,53 +1542,31 @@ static int nv_open(struct net_device *de
 		writel(mac[1], base + NvRegMacAddrB);
 	}
 
-	/* 4) continue setup */
+	/* 4) give hw rings */
+	writel((u32) np->ring_addr, base + NvRegRxRingPhysAddr);
+	writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr);
+	writel( ((RX_RING-1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING-1) << NVREG_RINGSZ_TXSHIFT),
+		base + NvRegRingSizes);
+
+	/* 5) continue setup */
 	np->linkspeed = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10;
 	np->duplex = 0;
+
+	writel(np->linkspeed, base + NvRegLinkSpeed);
 	writel(NVREG_UNKSETUP3_VAL1, base + NvRegUnknownSetupReg3);
-	writel(0, base + NvRegTxRxControl);
+	writel(np->desc_ver, base + NvRegTxRxControl);
 	pci_push(base);
-	writel(NVREG_TXRXCTL_BIT1, base + NvRegTxRxControl);
+	writel(NVREG_TXRXCTL_BIT1|np->desc_ver, base + NvRegTxRxControl);
 	reg_delay(dev, NvRegUnknownSetupReg5, NVREG_UNKSETUP5_BIT31, NVREG_UNKSETUP5_BIT31,
 			NV_SETUP5_DELAY, NV_SETUP5_DELAYMAX,
 			KERN_INFO "open: SetupReg5, Bit 31 remained off\n");
-	writel(0, base + NvRegUnknownSetupReg4);
-
-	/* 5) Find a suitable PHY */
-	writel(NVREG_MIISPEED_BIT8|NVREG_MIIDELAY, base + NvRegMIISpeed);
-	for (i = 1; i < 32; i++) {
-		int id1, id2;
 
-		spin_lock_irq(&np->lock);
-		id1 = mii_rw(dev, i, MII_PHYSID1, MII_READ);
-		spin_unlock_irq(&np->lock);
-		if (id1 < 0 || id1 == 0xffff)
-			continue;
-		spin_lock_irq(&np->lock);
-		id2 = mii_rw(dev, i, MII_PHYSID2, MII_READ);
-		spin_unlock_irq(&np->lock);
-		if (id2 < 0 || id2 == 0xffff)
-			continue;
-		dprintk(KERN_DEBUG "%s: open: Found PHY %04x:%04x at address %d.\n",
-				dev->name, id1, id2, i);
-		np->phyaddr = i;
-
-		spin_lock_irq(&np->lock);
-		nv_update_linkspeed(dev);
-		spin_unlock_irq(&np->lock);
-
-		break;
-	}
-	if (i == 32) {
-		printk(KERN_INFO "%s: open: failing due to lack of suitable PHY.\n",
-				dev->name);
-		ret = -EINVAL;
-		goto out_drain;
-	}
+	writel(0, base + NvRegUnknownSetupReg4);
+	writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
+	writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus);
 
 	/* 6) continue setup */
-	writel(NVREG_MISC1_FORCE | ( np->duplex ? 0 : NVREG_MISC1_HD),
-				base + NvRegMisc1);
+	writel(NVREG_MISC1_FORCE | NVREG_MISC1_HD, base + NvRegMisc1);
 	writel(readl(base + NvRegTransmitterStatus), base + NvRegTransmitterStatus);
 	writel(NVREG_PFF_ALWAYS, base + NvRegPacketFilterFlags);
 	writel(NVREG_OFFLOAD_NORMAL, base + NvRegOffloadConfig);
@@ -1290,17 +1578,12 @@ static int nv_open(struct net_device *de
 	writel(NVREG_UNKSETUP2_VAL, base + NvRegUnknownSetupReg2);
 	writel(NVREG_POLL_DEFAULT, base + NvRegPollingInterval);
 	writel(NVREG_UNKSETUP6_VAL, base + NvRegUnknownSetupReg6);
-	writel((np->phyaddr << NVREG_ADAPTCTL_PHYSHIFT)|NVREG_ADAPTCTL_PHYVALID,
+	writel((np->phyaddr << NVREG_ADAPTCTL_PHYSHIFT)|NVREG_ADAPTCTL_PHYVALID|NVREG_ADAPTCTL_RUNNING,
 			base + NvRegAdapterControl);
+	writel(NVREG_MIISPEED_BIT8|NVREG_MIIDELAY, base + NvRegMIISpeed);
 	writel(NVREG_UNKSETUP4_VAL, base + NvRegUnknownSetupReg4);
 	writel(NVREG_WAKEUPFLAGS_VAL, base + NvRegWakeUpFlags);
 
-	/* 7) start packet processing */
-	writel((u32) np->ring_addr, base + NvRegRxRingPhysAddr);
-	writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr);
-	writel( ((RX_RING-1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING-1) << NVREG_RINGSZ_TXSHIFT),
-			base + NvRegRingSizes);
-
 	i = readl(base + NvRegPowerState);
 	if ( (i & NVREG_POWERSTATE_POWEREDUP) == 0)
 		writel(NVREG_POWERSTATE_POWEREDUP|i, base + NvRegPowerState);
@@ -1308,13 +1591,9 @@ static int nv_open(struct net_device *de
 	pci_push(base);
 	udelay(10);
 	writel(readl(base + NvRegPowerState) | NVREG_POWERSTATE_VALID, base + NvRegPowerState);
-	writel(NVREG_ADAPTCTL_RUNNING, base + NvRegAdapterControl);
-
 
 	writel(0, base + NvRegIrqMask);
 	pci_push(base);
-	writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
-	pci_push(base);
 	writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus);
 	writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
 	pci_push(base);
@@ -1323,6 +1602,7 @@ static int nv_open(struct net_device *de
 	if (ret)
 		goto out_drain;
 
+	/* ask for interrupts */
 	writel(np->irqmask, base + NvRegIrqMask);
 
 	spin_lock_irq(&np->lock);
@@ -1331,18 +1611,27 @@ static int nv_open(struct net_device *de
 	writel(0, base + NvRegMulticastMaskA);
 	writel(0, base + NvRegMulticastMaskB);
 	writel(NVREG_PFF_ALWAYS|NVREG_PFF_MYADDR, base + NvRegPacketFilterFlags);
+	/* One manual link speed update: Interrupts are enabled, future link
+	 * speed changes cause interrupts and are handled by nv_link_irq().
+	 */
+	{
+		u32 miistat;
+		miistat = readl(base + NvRegMIIStatus);
+		writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus);
+		dprintk(KERN_INFO "startup: got 0x%08x.\n", miistat);
+	}
+	ret = nv_update_linkspeed(dev);
 	nv_start_rx(dev);
 	nv_start_tx(dev);
 	netif_start_queue(dev);
-	if (oom)
-		mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
-	if (mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ) & BMSR_ANEGCOMPLETE) {
+	if (ret) {
 		netif_carrier_on(dev);
 	} else {
 		printk("%s: no link during initialization.\n", dev->name);
 		netif_carrier_off(dev);
 	}
-
+	if (oom)
+		mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
 	spin_unlock_irq(&np->lock);
 
 	return 0;
@@ -1368,9 +1657,10 @@ static int nv_close(struct net_device *d
 	spin_lock_irq(&np->lock);
 	nv_stop_tx(dev);
 	nv_stop_rx(dev);
-	base = get_hwbase(dev);
+	nv_txrx_reset(dev);
 
 	/* disable interrupts on the nic or we will lock up */
+	base = get_hwbase(dev);
 	writel(0, base + NvRegIrqMask);
 	pci_push(base);
 	dprintk(KERN_INFO "%s: Irqmask is zero again\n", dev->name);
@@ -1424,7 +1714,7 @@ static int __devinit nv_probe(struct pci
 
 	pci_set_master(pci_dev);
 
-	err = pci_request_regions(pci_dev, dev->name);
+	err = pci_request_regions(pci_dev, DRV_NAME);
 	if (err < 0)
 		goto out_disable;
 
@@ -1447,6 +1737,14 @@ static int __devinit nv_probe(struct pci
 		goto out_relreg;
 	}
 
+	/* handle different descriptor versions */
+	if (pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_1 ||
+		pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_2 ||
+		pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_3)
+		np->desc_ver = DESC_VER_1;
+	else
+		np->desc_ver = DESC_VER_2;
+
 	err = -ENOMEM;
 	dev->base_addr = (unsigned long) ioremap(addr, NV_PCI_REGSZ);
 	if (!dev->base_addr)
@@ -1464,7 +1762,7 @@ static int __devinit nv_probe(struct pci
 	dev->get_stats = nv_get_stats;
 	dev->change_mtu = nv_change_mtu;
 	dev->set_multicast_list = nv_set_multicast;
-	dev->do_ioctl = nv_ioctl;
+	SET_ETHTOOL_OPS(dev, &ops);
 	dev->tx_timeout = nv_tx_timeout;
 	dev->watchdog_timeo = NV_WATCHDOG_TIMEO;
 
@@ -1506,15 +1804,65 @@ static int __devinit nv_probe(struct pci
 	writel(0, base + NvRegWakeUpFlags);
 	np->wolenabled = 0;
 
-	np->tx_flags = cpu_to_le16(NV_TX_LASTPACKET|NV_TX_LASTPACKET1|NV_TX_VALID);
-	if (id->driver_data & DEV_NEED_LASTPACKET1)
-		np->tx_flags |= cpu_to_le16(NV_TX_LASTPACKET1);
+	if (np->desc_ver == DESC_VER_1) {
+		np->tx_flags = NV_TX_LASTPACKET|NV_TX_VALID;
+		if (id->driver_data & DEV_NEED_LASTPACKET1)
+			np->tx_flags |= NV_TX_LASTPACKET1;
+	} else {
+		np->tx_flags = NV_TX2_LASTPACKET|NV_TX2_VALID;
+		if (id->driver_data & DEV_NEED_LASTPACKET1)
+			np->tx_flags |= NV_TX2_LASTPACKET1;
+	}
 	if (id->driver_data & DEV_IRQMASK_1)
 		np->irqmask = NVREG_IRQMASK_WANTED_1;
 	if (id->driver_data & DEV_IRQMASK_2)
 		np->irqmask = NVREG_IRQMASK_WANTED_2;
 	if (id->driver_data & DEV_NEED_TIMERIRQ)
 		np->irqmask |= NVREG_IRQ_TIMER;
+	if (id->driver_data & DEV_NEED_LINKTIMER) {
+		dprintk(KERN_INFO "%s: link timer on.\n", pci_name(pci_dev));
+		np->need_linktimer = 1;
+		np->link_timeout = jiffies + LINK_TIMEOUT;
+	} else {
+		dprintk(KERN_INFO "%s: link timer off.\n", pci_name(pci_dev));
+		np->need_linktimer = 0;
+	}
+
+	/* find a suitable phy */
+	for (i = 1; i < 32; i++) {
+		int id1, id2;
+
+		spin_lock_irq(&np->lock);
+		id1 = mii_rw(dev, i, MII_PHYSID1, MII_READ);
+		spin_unlock_irq(&np->lock);
+		if (id1 < 0 || id1 == 0xffff)
+			continue;
+		spin_lock_irq(&np->lock);
+		id2 = mii_rw(dev, i, MII_PHYSID2, MII_READ);
+		spin_unlock_irq(&np->lock);
+		if (id2 < 0 || id2 == 0xffff)
+			continue;
+
+		id1 = (id1 & PHYID1_OUI_MASK) << PHYID1_OUI_SHFT;
+		id2 = (id2 & PHYID2_OUI_MASK) >> PHYID2_OUI_SHFT;
+		dprintk(KERN_DEBUG "%s: open: Found PHY %04x:%04x at address %d.\n",
+				pci_name(pci_dev), id1, id2, i);
+		np->phyaddr = i;
+		np->phy_oui = id1 | id2;
+		break;
+	}
+	if (i == 32) {
+		/* PHY in isolate mode? No phy attached and user wants to
+		 * test loopback? Very odd, but can be correct.
+		 */
+		printk(KERN_INFO "%s: open: Could not find a valid PHY.\n",
+				pci_name(pci_dev));
+	}
+
+	if (i != 32) {
+		/* reset it */
+		phy_init(dev);
+	}
 
 	err = register_netdev(dev);
 	if (err) {
@@ -1569,21 +1917,77 @@ static void __devexit nv_remove(struct p
 static struct pci_device_id pci_tbl[] = {
 	{	/* nForce Ethernet Controller */
 		.vendor = PCI_VENDOR_ID_NVIDIA,
-		.device = 0x1C3,
+		.device = PCI_DEVICE_ID_NVIDIA_NVENET_1,
 		.subvendor = PCI_ANY_ID,
 		.subdevice = PCI_ANY_ID,
-		.driver_data = DEV_IRQMASK_1|DEV_NEED_TIMERIRQ,
+		.driver_data = DEV_IRQMASK_1|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
 	},
 	{	/* nForce2 Ethernet Controller */
 		.vendor = PCI_VENDOR_ID_NVIDIA,
-		.device = 0x0066,
+		.device = PCI_DEVICE_ID_NVIDIA_NVENET_2,
+		.subvendor = PCI_ANY_ID,
+		.subdevice = PCI_ANY_ID,
+		.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
+	},
+	{	/* nForce3 Ethernet Controller */
+		.vendor = PCI_VENDOR_ID_NVIDIA,
+		.device = PCI_DEVICE_ID_NVIDIA_NVENET_3,
+		.subvendor = PCI_ANY_ID,
+		.subdevice = PCI_ANY_ID,
+		.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
+	},
+	{	/* nForce3 Ethernet Controller */
+		.vendor = PCI_VENDOR_ID_NVIDIA,
+		.device = PCI_DEVICE_ID_NVIDIA_NVENET_4,
 		.subvendor = PCI_ANY_ID,
 		.subdevice = PCI_ANY_ID,
 		.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ,
 	},
 	{	/* nForce3 Ethernet Controller */
 		.vendor = PCI_VENDOR_ID_NVIDIA,
-		.device = 0x00D6,
+		.device = PCI_DEVICE_ID_NVIDIA_NVENET_5,
+		.subvendor = PCI_ANY_ID,
+		.subdevice = PCI_ANY_ID,
+		.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ,
+	},
+	{	/* nForce3 Ethernet Controller */
+		.vendor = PCI_VENDOR_ID_NVIDIA,
+		.device = PCI_DEVICE_ID_NVIDIA_NVENET_6,
+		.subvendor = PCI_ANY_ID,
+		.subdevice = PCI_ANY_ID,
+		.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ,
+	},
+	{	/* nForce3 Ethernet Controller */
+		.vendor = PCI_VENDOR_ID_NVIDIA,
+		.device = PCI_DEVICE_ID_NVIDIA_NVENET_7,
+		.subvendor = PCI_ANY_ID,
+		.subdevice = PCI_ANY_ID,
+		.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ,
+	},
+	{	/* CK804 Ethernet Controller */
+		.vendor = PCI_VENDOR_ID_NVIDIA,
+		.device = PCI_DEVICE_ID_NVIDIA_NVENET_8,
+		.subvendor = PCI_ANY_ID,
+		.subdevice = PCI_ANY_ID,
+		.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ,
+	},
+	{	/* CK804 Ethernet Controller */
+		.vendor = PCI_VENDOR_ID_NVIDIA,
+		.device = PCI_DEVICE_ID_NVIDIA_NVENET_9,
+		.subvendor = PCI_ANY_ID,
+		.subdevice = PCI_ANY_ID,
+		.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ,
+	},
+	{	/* MCP04 Ethernet Controller */
+		.vendor = PCI_VENDOR_ID_NVIDIA,
+		.device = PCI_DEVICE_ID_NVIDIA_NVENET_10,
+		.subvendor = PCI_ANY_ID,
+		.subdevice = PCI_ANY_ID,
+		.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ,
+	},
+	{	/* MCP04 Ethernet Controller */
+		.vendor = PCI_VENDOR_ID_NVIDIA,
+		.device = PCI_DEVICE_ID_NVIDIA_NVENET_11,
 		.subvendor = PCI_ANY_ID,
 		.subdevice = PCI_ANY_ID,
 		.driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ,
@@ -1610,7 +2014,7 @@ static void __exit exit_nic(void)
 	pci_unregister_driver(&driver);
 }
 
-MODULE_PARM(max_interrupt_work, "i");
+module_param(max_interrupt_work, int, 0);
 MODULE_PARM_DESC(max_interrupt_work, "forcedeth maximum events handled per interrupt");
  
 MODULE_AUTHOR("Manfred Spraul <manfred@colorfullife.com>");
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/net/hamradio/6pack.c linux-2.4.29-pre3/drivers/net/hamradio/6pack.c
--- linux-2.4.28/drivers/net/hamradio/6pack.c	2004-08-07 23:26:05.000000000 +0000
+++ linux-2.4.29-pre3/drivers/net/hamradio/6pack.c	2004-12-22 16:05:53.556277536 +0000
@@ -571,8 +571,7 @@ static int sixpack_open(struct tty_struc
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
 
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	tty_ldisc_flush(tty);
 
 	/* Restore default settings */
 	sp->dev->type = ARPHRD_AX25;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/net/hamradio/mkiss.c linux-2.4.29-pre3/drivers/net/hamradio/mkiss.c
--- linux-2.4.28/drivers/net/hamradio/mkiss.c	2003-08-25 11:44:42.000000000 +0000
+++ linux-2.4.29-pre3/drivers/net/hamradio/mkiss.c	2004-12-22 16:06:34.885994464 +0000
@@ -654,8 +654,7 @@ static int ax25_open(struct tty_struct *
 
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	tty_ldisc_flush(tty);
 
 	/* Restore default settings */
 	ax->dev->type = ARPHRD_AX25;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/net/irda/irtty.c linux-2.4.29-pre3/drivers/net/irda/irtty.c
--- linux-2.4.28/drivers/net/irda/irtty.c	2003-06-13 14:51:35.000000000 +0000
+++ linux-2.4.29-pre3/drivers/net/irda/irtty.c	2004-12-22 16:06:02.755878984 +0000
@@ -179,9 +179,8 @@ static int irtty_open(struct tty_struct 
 
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-	
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+
+	tty_ldisc_flush(tty);	
 	
 	self->magic = IRTTY_MAGIC;
 	self->mode = IRDA_IRLAP;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/net/ppp_async.c linux-2.4.29-pre3/drivers/net/ppp_async.c
--- linux-2.4.28/drivers/net/ppp_async.c	2002-08-03 00:39:44.000000000 +0000
+++ linux-2.4.29-pre3/drivers/net/ppp_async.c	2004-12-22 16:07:16.431678560 +0000
@@ -117,6 +117,9 @@ static struct ppp_channel_ops async_ops 
  * frees the memory that ppp_asynctty_receive is using.  The best
  * way to fix this is to use a rwlock in the tty struct, but for now
  * we use a single global rwlock for all ttys in ppp line discipline.
+ *
+ * FIXME: this is no longer true. The _close path for the ldisc is 
+ * now guaranteed to be sane. 
  */
 static rwlock_t disc_data_lock = RW_LOCK_UNLOCKED;
 
@@ -139,7 +142,8 @@ static void ap_put(struct asyncppp *ap)
 }
 
 /*
- * Called when a tty is put into PPP line discipline.
+ * Called when a tty is put into PPP line discipline. Called in process
+ * context.
  */
 static int
 ppp_asynctty_open(struct tty_struct *tty)
@@ -227,6 +231,18 @@ ppp_asynctty_close(struct tty_struct *tt
 }
 
 /*
+ * Called on tty hangup in process context.
+ *
+ * Wait for I/O to driver to complete and unregister PPP channel.
+ * This is already done by the close routine, so just call that.
+ */
+static int ppp_asynctty_hangup(struct tty_struct *tty)
+{
+	ppp_asynctty_close(tty);
+	return 0;
+}
+
+/*
  * Read does nothing - no data is ever available this way.
  * Pppd reads and writes packets via /dev/ppp instead.
  */
@@ -248,6 +264,11 @@ ppp_asynctty_write(struct tty_struct *tt
 	return -EAGAIN;
 }
 
+/*
+ * Called in process context only. May be re-entered by multiple
+ * ioctl calling threads.
+ */
+ 
 static int
 ppp_asynctty_ioctl(struct tty_struct *tty, struct file *file,
 		   unsigned int cmd, unsigned long arg)
@@ -359,6 +380,7 @@ static struct tty_ldisc ppp_ldisc = {
 	write:	ppp_asynctty_write,
 	ioctl:	ppp_asynctty_ioctl,
 	poll:	ppp_asynctty_poll,
+	hangup: ppp_asynctty_hangup,
 	receive_room: ppp_asynctty_room,
 	receive_buf: ppp_asynctty_receive,
 	write_wakeup: ppp_asynctty_wakeup,
@@ -714,7 +736,8 @@ flush:
 
 /*
  * Flush output from our internal buffers.
- * Called for the TCFLSH ioctl.
+ * Called for the TCFLSH ioctl. Can be entered in parallel
+ * but this is covered by the xmit_lock.
  */
 static void
 ppp_async_flush_output(struct asyncppp *ap)
@@ -819,7 +842,9 @@ input_error(struct asyncppp *ap, int cod
 	ppp_input_error(&ap->chan, code);
 }
 
-/* called when the tty driver has data for us. */
+/* Called when the tty driver has data for us. Runs parallel with the
+   other ldisc functions but will not be re-entered */
+
 static void
 ppp_async_input(struct asyncppp *ap, const unsigned char *buf,
 		char *flags, int count)
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/net/ppp_synctty.c linux-2.4.29-pre3/drivers/net/ppp_synctty.c
--- linux-2.4.28/drivers/net/ppp_synctty.c	2002-08-03 00:39:44.000000000 +0000
+++ linux-2.4.29-pre3/drivers/net/ppp_synctty.c	2004-12-22 16:06:31.611492264 +0000
@@ -172,6 +172,8 @@ ppp_print_buffer (const char *name, cons
  * frees the memory that ppp_synctty_receive is using.  The best
  * way to fix this is to use a rwlock in the tty struct, but for now
  * we use a single global rwlock for all ttys in ppp line discipline.
+ *
+ * FIXME: Fixed in tty_io nowdays.
  */
 static rwlock_t disc_data_lock = RW_LOCK_UNLOCKED;
 
@@ -280,6 +282,18 @@ ppp_sync_close(struct tty_struct *tty)
 }
 
 /*
+ * Called on tty hangup in process context.
+ *
+ * Wait for I/O to driver to complete and unregister PPP channel.
+ * This is already done by the close routine, so just call that.
+ */
+static int ppp_sync_hangup(struct tty_struct *tty)
+{
+	ppp_sync_close(tty);
+	return 0;
+}
+
+/*
  * Read does nothing - no data is ever available this way.
  * Pppd reads and writes packets via /dev/ppp instead.
  */
@@ -412,6 +426,7 @@ static struct tty_ldisc ppp_sync_ldisc =
 	write:	ppp_sync_write,
 	ioctl:	ppp_synctty_ioctl,
 	poll:	ppp_sync_poll,
+	hangup: ppp_sync_hangup,
 	receive_room: ppp_sync_room,
 	receive_buf: ppp_sync_receive,
 	write_wakeup: ppp_sync_wakeup,
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/net/slip.c linux-2.4.29-pre3/drivers/net/slip.c
--- linux-2.4.28/drivers/net/slip.c	2002-11-28 23:53:14.000000000 +0000
+++ linux-2.4.29-pre3/drivers/net/slip.c	2004-12-22 16:07:55.263775184 +0000
@@ -670,7 +670,9 @@ static int slip_receive_room(struct tty_
  * Handle the 'receiver data ready' interrupt.
  * This function is called by the 'tty_io' module in the kernel when
  * a block of SLIP data has been received, which can now be decapsulated
- * and sent on to some IP layer for further processing.
+ * and sent on to some IP layer for further processing. This will not
+ * be re-entered while running but other ldisc functions may be called
+ * in parallel
  */
  
 static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
@@ -826,9 +828,11 @@ sl_alloc(kdev_t line)
  * SLIP line discipline is called for.  Because we are
  * sure the tty line exists, we only have to link it to
  * a free SLIP channel...
+ *
+ * Called in process context serialized from other ldisc calls.
  */
-static int
-slip_open(struct tty_struct *tty)
+
+static int slip_open(struct tty_struct *tty)
 {
 	struct slip *sl;
 	int err;
@@ -865,8 +869,6 @@ slip_open(struct tty_struct *tty)
 	sl->pid = current->pid;
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
 
 	if (!test_bit(SLF_INUSE, &sl->flags)) {
 		/* Perform the low-level SLIP initialization. */
@@ -910,6 +912,9 @@ err_exit:
 }
 
 /*
+
+  FIXME: 1,2 are fixed 3 was never true anyway.
+  
    Let me to blame a bit.
    1. TTY module calls this funstion on soft interrupt.
    2. TTY module calls this function WITH MASKED INTERRUPTS!
@@ -928,9 +933,8 @@ err_exit:
 
 /*
  * Close down a SLIP channel.
- * This means flushing out any pending queues, and then restoring the
- * TTY line discipline to what it was before it got hooked to SLIP
- * (which usually is TTY again).
+ * This means flushing out any pending queues, and then returning. This
+ * call is serialized against other ldisc functions.
  */
 static void
 slip_close(struct tty_struct *tty)
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/net/strip.c linux-2.4.29-pre3/drivers/net/strip.c
--- linux-2.4.28/drivers/net/strip.c	2001-11-09 22:02:24.000000000 +0000
+++ linux-2.4.29-pre3/drivers/net/strip.c	2004-12-22 16:07:13.848071328 +0000
@@ -2706,8 +2706,7 @@ static int strip_open(struct tty_struct 
     tty->disc_data = strip_info;
     if (tty->driver.flush_buffer)
         tty->driver.flush_buffer(tty);
-    if (tty->ldisc.flush_buffer)
-        tty->ldisc.flush_buffer(tty);
+    tty_ldisc_flush(tty);
 
     /*
      * Restore default settings
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/net/wan/8253x/8253xsyn.c linux-2.4.29-pre3/drivers/net/wan/8253x/8253xsyn.c
--- linux-2.4.28/drivers/net/wan/8253x/8253xsyn.c	2002-08-03 00:39:44.000000000 +0000
+++ linux-2.4.29-pre3/drivers/net/wan/8253x/8253xsyn.c	2004-12-22 16:07:07.265072096 +0000
@@ -1108,10 +1108,7 @@ void sab8253x_closeS(struct tty_struct *
 	{
 		tty->driver.flush_buffer(tty);
 	}
-	if (tty->ldisc.flush_buffer)
-	{
-		tty->ldisc.flush_buffer(tty);
-	}
+	tty_ldisc_flush(tty);
 	tty->closing = 0;
 	port->event = 0;
 	port->tty = 0;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/net/wan/8253x/8253xtty.c linux-2.4.29-pre3/drivers/net/wan/8253x/8253xtty.c
--- linux-2.4.28/drivers/net/wan/8253x/8253xtty.c	2003-06-13 14:51:35.000000000 +0000
+++ linux-2.4.29-pre3/drivers/net/wan/8253x/8253xtty.c	2004-12-22 16:07:02.277830272 +0000
@@ -691,10 +691,7 @@ static void sab8253x_do_softint(void *pr
 	port->DoingInterrupt = 1;
 	if (test_and_clear_bit(SAB8253X_EVENT_WRITE_WAKEUP, &port->event)) 
 	{
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup)(tty);
-		wake_up_interruptible(&tty->write_wait); /* in case tty driver waiting on write */
+		tty_wakeup(tty);
 	}
 	port->DoingInterrupt = 0;
 }
@@ -2001,10 +1998,7 @@ static void sab8253x_close(struct tty_st
 	{
 		tty->driver.flush_buffer(tty);
 	}
-	if (tty->ldisc.flush_buffer)
-	{
-		tty->ldisc.flush_buffer(tty);
-	}
+	tty_ldisc_flush(tty);
 	tty->closing = 0;
 	port->event = 0;
 	port->tty = 0;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/net/wan/8253x/8253xutl.c linux-2.4.29-pre3/drivers/net/wan/8253x/8253xutl.c
--- linux-2.4.28/drivers/net/wan/8253x/8253xutl.c	2002-08-03 00:39:44.000000000 +0000
+++ linux-2.4.29-pre3/drivers/net/wan/8253x/8253xutl.c	2004-12-22 16:05:31.524626856 +0000
@@ -1412,11 +1412,6 @@ void sab8253x_flush_buffer(struct tty_st
 	WRITEB(port,cmdr,SAB82532_CMDR_XRES);
 	restore_flags(flags);
 	
-	wake_up_interruptible(&tty->write_wait); /* wake up tty driver */
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-	{
-		(*tty->ldisc.write_wakeup)(tty);
-	}
+	tty_wakeup(tty);
 }
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/net/wan/pc300_tty.c linux-2.4.29-pre3/drivers/net/wan/pc300_tty.c
--- linux-2.4.28/drivers/net/wan/pc300_tty.c	2004-12-22 16:17:17.436311968 +0000
+++ linux-2.4.29-pre3/drivers/net/wan/pc300_tty.c	2004-12-22 16:06:25.636400616 +0000
@@ -627,14 +627,8 @@ static void cpc_tty_flush_buffer(struct 
 	}
 
 	CPC_TTY_DBG("%s: call wake_up_interruptible\n",cpc_tty->name);
-	
-	wake_up_interruptible(&tty->write_wait); 
-
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup){
-		CPC_TTY_DBG("%s: call line disc. wake up\n",cpc_tty->name);
-		tty->ldisc.write_wakeup(tty); 
-	} 
 
+	tty_wakeup(tty);	
 	return; 
 } 
 
@@ -699,12 +693,19 @@ static void cpc_tty_rx_task(void * data)
 			cpc_tty = &cpc_tty_area[port];
 		
 			if ((buf=cpc_tty->buf_rx.first) != 0) {
-															
-				if (cpc_tty->tty && (cpc_tty->tty->ldisc.receive_buf)) { 
-					CPC_TTY_DBG("%s: call line disc. receive_buf\n",cpc_tty->name);
-					cpc_tty->tty->ldisc.receive_buf(cpc_tty->tty, (const unsigned char *)buf->data, 
-													&flags, buf->size);
-				}	
+				
+				if(cpc_tty->tty) 
+				{
+					struct tty_ldisc *ld = tty_ldisc_ref(cpc_tty->tty);
+					if(ld)
+					{
+						if (ld->receive_buf) {
+							CPC_TTY_DBG("%s: call line disc. receive_buf\n",cpc_tty->name);
+							ld->receive_buf(cpc_tty->tty, (char *)(buf->data), &flags, buf->size);
+						}
+						tty_ldisc_deref(ld);
+					}
+				}											
 				cpc_tty->buf_rx.first = cpc_tty->buf_rx.first->next;
 				kfree((unsigned char *)buf);
 				buf = cpc_tty->buf_rx.first;
@@ -908,12 +909,7 @@ static void cpc_tty_tx_task(void *data)
 		return; 
 	}
 
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup){
-		CPC_TTY_DBG("%s:call line disc. wakeup\n",cpc_tty->name);
-		tty->ldisc.write_wakeup (tty); 
-	}
-
-	wake_up_interruptible(&tty->write_wait); 
+	tty_wakeup(tty);
 }
 
 /*
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/net/wan/sdla_chdlc.c linux-2.4.29-pre3/drivers/net/wan/sdla_chdlc.c
--- linux-2.4.28/drivers/net/wan/sdla_chdlc.c	2003-11-28 18:26:20.000000000 +0000
+++ linux-2.4.29-pre3/drivers/net/wan/sdla_chdlc.c	2004-12-22 16:06:43.475688632 +0000
@@ -3868,11 +3868,7 @@ static void tty_poll_task (void* data)
 	if ((tty=card->tty)==NULL)
 		return;
 	
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup){
-		(tty->ldisc.write_wakeup)(tty);
-	}
-	wake_up_interruptible(&tty->write_wait);
+	tty_wakeup(tty);
 #if defined(SERIAL_HAVE_POLL_WAIT) || \
          (defined LINUX_2_1 && LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,15))
 	wake_up_interruptible(&tty->poll_wait);
@@ -4098,6 +4094,7 @@ static void wanpipe_tty_receive(sdla_t *
 	char fp=0;
 	struct tty_struct *tty;
 	int i;
+	struct tty_ldisc *ld;
 	
 	if (!card->tty_open){
 		dbg_printk(KERN_INFO "%s: TTY not open during receive\n",
@@ -4185,8 +4182,11 @@ static void wanpipe_tty_receive(sdla_t *
 			len -= offset;
 		}
 		sdla_peek(&card->hw, addr, card->tty_rx+offset, len);
-		if (tty->ldisc.receive_buf){
-			tty->ldisc.receive_buf(tty,card->tty_rx,&fp,olen);
+		ld = tty_ldisc_ref(tty);
+		if (ld) {
+			if (ld->receive_buf)
+				ld->receive_buf(tty,card->tty_rx,&fp,olen);
+			tty_ldisc_deref(ld);
 		}else{
 			if (net_ratelimit()){
 				printk(KERN_INFO 
@@ -4493,14 +4493,11 @@ static void wanpipe_tty_flush_buffer(str
 	if (!tty)
 		return;
 	
-	wake_up_interruptible(&tty->write_wait);
 #if defined(SERIAL_HAVE_POLL_WAIT) || \
          (defined LINUX_2_1 && LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,15))
 	wake_up_interruptible(&tty->poll_wait);
 #endif
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
+	tty_wakeup(tty);
 
 	return;
 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/net/wan/x25_asy.c linux-2.4.29-pre3/drivers/net/wan/x25_asy.c
--- linux-2.4.28/drivers/net/wan/x25_asy.c	2001-09-13 23:04:43.000000000 +0000
+++ linux-2.4.29-pre3/drivers/net/wan/x25_asy.c	2004-12-22 16:05:58.056593384 +0000
@@ -619,9 +619,7 @@ static int x25_asy_open_tty(struct tty_s
 	if (tty->driver.flush_buffer)  {
 		tty->driver.flush_buffer(tty);
 	}
-	if (tty->ldisc.flush_buffer)  {
-		tty->ldisc.flush_buffer(tty);
-	}
+	tty_ldisc_flush(tty);
 
 	/* Restore default settings */
 	sl->dev->type = ARPHRD_X25;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/net/wd.c linux-2.4.29-pre3/drivers/net/wd.c
--- linux-2.4.28/drivers/net/wd.c	2002-11-28 23:53:14.000000000 +0000
+++ linux-2.4.29-pre3/drivers/net/wd.c	2004-12-22 16:05:33.112385480 +0000
@@ -151,7 +151,7 @@ static int __init wd_probe1(struct net_d
 		printk(" %2.2X", dev->dev_addr[i] = inb(ioaddr + 8 + i));
 
 	/* The following PureData probe code was contributed by
-	   Mike Jagdis <jaggy@purplet.demon.co.uk>. Puredata does software
+	   Mike Jagdis <mjagdis@eris-associates.co.uk>. Puredata does software
 	   configuration differently from others so we have to check for them.
 	   This detects an 8 bit, 16 bit or dumb (Toshiba, jumpered) card.
 	   */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/parport/ieee1284.c linux-2.4.29-pre3/drivers/parport/ieee1284.c
--- linux-2.4.28/drivers/parport/ieee1284.c	2001-10-25 07:07:39.000000000 +0000
+++ linux-2.4.29-pre3/drivers/parport/ieee1284.c	2004-12-22 16:05:37.517715768 +0000
@@ -1,7 +1,7 @@
 /* $Id: parport_ieee1284.c,v 1.4 1997/10/19 21:37:21 philip Exp $
  * IEEE-1284 implementation for parport.
  *
- * Authors: Phil Blundell <Philip.Blundell@pobox.com>
+ * Authors: Phil Blundell <philb@gnu.org>
  *          Carsten Gross <carsten@sol.wohnheim.uni-ulm.de>
  *	    Jose Renau <renau@acm.org>
  *          Tim Waugh <tim@cyberelk.demon.co.uk> (largely rewritten)
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/parport/parport_arc.c linux-2.4.29-pre3/drivers/parport/parport_arc.c
--- linux-2.4.28/drivers/parport/parport_arc.c	2001-02-09 19:30:23.000000000 +0000
+++ linux-2.4.29-pre3/drivers/parport/parport_arc.c	2004-12-22 16:05:30.880724744 +0000
@@ -1,6 +1,6 @@
 /* Low-level parallel port routines for Archimedes onboard hardware
  *
- * Author: Phil Blundell <Philip.Blundell@pobox.com>
+ * Author: Phil Blundell <philb@gnu.org>
  */
 
 /* This driver is for the parallel port hardware found on Acorn's old
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/parport/parport_gsc.c linux-2.4.29-pre3/drivers/parport/parport_gsc.c
--- linux-2.4.28/drivers/parport/parport_gsc.c	2002-11-28 23:53:14.000000000 +0000
+++ linux-2.4.29-pre3/drivers/parport/parport_gsc.c	2004-12-22 16:06:19.670307600 +0000
@@ -12,7 +12,7 @@
  * 
  * based on parport_pc.c by 
  * 	    Grant Guenther <grant@torque.net>
- * 	    Phil Blundell <Philip.Blundell@pobox.com>
+ * 	    Phil Blundell <philb@gnu.org>
  *          Tim Waugh <tim@cyberelk.demon.co.uk>
  *	    Jose Renau <renau@acm.org>
  *          David Campbell <campbell@torque.net>
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/parport/parport_pc.c linux-2.4.29-pre3/drivers/parport/parport_pc.c
--- linux-2.4.28/drivers/parport/parport_pc.c	2004-12-22 16:17:17.661277768 +0000
+++ linux-2.4.29-pre3/drivers/parport/parport_pc.c	2004-12-22 16:06:34.116111504 +0000
@@ -1,6 +1,6 @@
 /* Low-level parallel-port routines for 8255-based PC-style hardware.
  * 
- * Authors: Phil Blundell <Philip.Blundell@pobox.com>
+ * Authors: Phil Blundell <philb@gnu.org>
  *          Tim Waugh <tim@cyberelk.demon.co.uk>
  *	    Jose Renau <renau@acm.org>
  *          David Campbell <campbell@torque.net>
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/parport/parport_sunbpp.c linux-2.4.29-pre3/drivers/parport/parport_sunbpp.c
--- linux-2.4.28/drivers/parport/parport_sunbpp.c	2001-06-12 02:15:27.000000000 +0000
+++ linux-2.4.29-pre3/drivers/parport/parport_sunbpp.c	2004-12-22 16:05:44.513652224 +0000
@@ -4,7 +4,7 @@
  * Author: Derrick J. Brashear <shadow@dementia.org>
  *
  * based on work by:
- *          Phil Blundell <Philip.Blundell@pobox.com>
+ *          Phil Blundell <philb@gnu.org>
  *          Tim Waugh <tim@cyberelk.demon.co.uk>
  *	    Jose Renau <renau@acm.org>
  *          David Campbell <campbell@tirian.che.curtin.edu.au>
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/parport/probe.c linux-2.4.29-pre3/drivers/parport/probe.c
--- linux-2.4.28/drivers/parport/probe.c	2001-05-23 02:54:04.000000000 +0000
+++ linux-2.4.29-pre3/drivers/parport/probe.c	2004-12-22 16:06:15.818893104 +0000
@@ -2,7 +2,7 @@
  * Parallel port device probing code
  *
  * Authors:    Carsten Gross, carsten@sol.wohnheim.uni-ulm.de
- *             Philip Blundell <Philip.Blundell@pobox.com>
+ *             Philip Blundell <philb@gnu.org>
  */
 
 #include <linux/parport.h>
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/pcmcia/au1000_db1x00.c linux-2.4.29-pre3/drivers/pcmcia/au1000_db1x00.c
--- linux-2.4.28/drivers/pcmcia/au1000_db1x00.c	2003-08-25 11:44:42.000000000 +0000
+++ linux-2.4.29-pre3/drivers/pcmcia/au1000_db1x00.c	2004-12-22 16:06:04.798568448 +0000
@@ -56,7 +56,7 @@
 
 #include <asm/db1x00.h>
 
-static BCSR * const bcsr = (BCSR *)0xAE000000;
+static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
 
 static int db1x00_pcmcia_init(struct pcmcia_init *init)
 {
@@ -143,11 +143,16 @@ static int db1x00_pcmcia_get_irq_info(st
 {
 	if(info->sock > PCMCIA_MAX_SOCK) return -1;
 
-	if(info->sock == 0) {
+	if(info->sock == 0)
+#ifdef CONFIG_MIPS_DB1550
+		info->irq = AU1000_GPIO_3;
+	else 
+		info->irq = AU1000_GPIO_5;
+#else
 		info->irq = AU1000_GPIO_2;
-	}
 	else 
 		info->irq = AU1000_GPIO_5;
+#endif
 
 	return 0;
 }
@@ -260,7 +265,7 @@ db1x00_pcmcia_configure_socket(const str
 	return 0;
 }
 
-struct pcmcia_low_level db1x00_pcmcia_ops = { 
+struct pcmcia_low_level au1x00_pcmcia_ops = { 
 	db1x00_pcmcia_init,
 	db1x00_pcmcia_shutdown,
 	db1x00_pcmcia_socket_state,
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/pcmcia/au1000_generic.c linux-2.4.29-pre3/drivers/pcmcia/au1000_generic.c
--- linux-2.4.28/drivers/pcmcia/au1000_generic.c	2003-08-25 11:44:42.000000000 +0000
+++ linux-2.4.29-pre3/drivers/pcmcia/au1000_generic.c	2004-12-22 16:07:32.750197768 +0000
@@ -70,7 +70,12 @@ MODULE_DESCRIPTION("Linux PCMCIA Card Se
  * callback value associated with the socket:
  */
 static struct au1000_pcmcia_socket *pcmcia_socket;
-static int socket_count;
+
+/* Some boards like to support CF cards as IDE root devices, so they
+ * grab pcmcia sockets directly.
+ */
+int socket_count;
+u32 *pcmcia_base_vaddrs[2];
 
 
 /* Returned by the low-level PCMCIA interface: */
@@ -157,16 +162,7 @@ static int __init au1000_pcmcia_driver_i
 		return -1;
 	}
 
-#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_PB1500)
-	pcmcia_low_level=&pb1x00_pcmcia_ops;
-#elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500)
-	pcmcia_low_level=&db1x00_pcmcia_ops;
-#elif defined(CONFIG_MIPS_XXS1500)
-	pcmcia_low_level=&xxs1500_pcmcia_ops;
-#else
-#error Unsupported AU1000 board.
-#endif
-
+	pcmcia_low_level=&au1x00_pcmcia_ops;
 	pcmcia_init.handler=au1000_pcmcia_interrupt;
 	if((socket_count=pcmcia_low_level->init(&pcmcia_init))<0) {
 		printk(KERN_ERR "Unable to initialize PCMCIA service.\n");
@@ -205,7 +201,7 @@ static int __init au1000_pcmcia_driver_i
 		 * access address, we need to subtract it here.
 		 */
 		if (i == 0) {
-			pcmcia_socket[i].virt_io = 
+			pcmcia_socket[i].virt_io =
 				(u32)ioremap((ioaddr_t)AU1X_SOCK0_IO, 0x1000) -
 				mips_io_port_base;
 			pcmcia_socket[i].phys_attr = 
@@ -213,7 +209,7 @@ static int __init au1000_pcmcia_driver_i
 			pcmcia_socket[i].phys_mem = 
 				(ioaddr_t)AU1X_SOCK0_PHYS_MEM;
 		}
-#ifndef CONFIG_MIPS_XXS1500
+#ifdef AU1X_SOCK1_IO /* revisit */
 		else  {
 			pcmcia_socket[i].virt_io = 
 				(u32)ioremap((ioaddr_t)AU1X_SOCK1_IO, 0x1000) -
@@ -224,6 +220,7 @@ static int __init au1000_pcmcia_driver_i
 				(ioaddr_t)AU1X_SOCK1_PHYS_MEM;
 		}
 #endif
+		pcmcia_base_vaddrs[i] = (u32 *)pcmcia_socket[i].virt_io;
 	}
 
 	/* Only advertise as many sockets as we can detect: */
@@ -607,7 +604,6 @@ au1000_pcmcia_set_mem_map(unsigned int s
 	}
 
 	spin_lock_irqsave(&pcmcia_lock, flags);
-	start=map->sys_start;
 
 	if(map->sys_stop==0)
 		map->sys_stop=MAP_SIZE-1;
@@ -621,7 +617,7 @@ au1000_pcmcia_set_mem_map(unsigned int s
 			map->card_start;
 	}
 
-	map->sys_stop=map->sys_start+(map->sys_stop-start);
+	map->sys_stop=map->sys_start+MAP_SIZE;
 	pcmcia_socket[sock].mem_map[map->map]=*map;
 	spin_unlock_irqrestore(&pcmcia_lock, flags);
 	DEBUG(3, "set_mem_map %d start %x stop %x card_start %x\n", 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/pcmcia/au1000_hydrogen3.c linux-2.4.29-pre3/drivers/pcmcia/au1000_hydrogen3.c
--- linux-2.4.28/drivers/pcmcia/au1000_hydrogen3.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/drivers/pcmcia/au1000_hydrogen3.c	2004-12-22 16:06:48.384942312 +0000
@@ -0,0 +1,152 @@
+/*
+ *
+ * Alchemy Semi Hydrogen III board specific pcmcia routines.
+ *
+ * based on:
+ *
+ * Alchemy Semi Hyd1100 board specific pcmcia routines.
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * 
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/tqueue.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/proc_fs.h>
+#include <linux/version.h>
+#include <linux/types.h>
+
+#include <pcmcia/version.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/ss.h>
+#include <pcmcia/bulkmem.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/bus_ops.h>
+#include "cs_internal.h"
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+#include <asm/au1000.h>
+#include <asm/au1000_pcmcia.h>
+
+#include <asm/db1x00.h>
+
+#define PCMCIA_MAX_SOCK 0
+//#include <asm/hyd1100.h>
+
+
+static int hydrogen3_pcmcia_init(struct pcmcia_init *init)
+{
+	// power up
+	writel(0x00020002, GPIO2_OUTPUT); // GPIO_201 CF_PWR
+	return 1; // one slot
+}
+
+static int hydrogen3_pcmcia_shutdown(void)
+{
+	// power down
+	writel(0x00020000, GPIO2_OUTPUT); // GPIO_201 CF_PWR
+	return 0; 
+}
+
+static int 
+hydrogen3_pcmcia_socket_state(unsigned sock, struct pcmcia_state *state)
+{
+	u32 inserted;
+	inserted = (readl(SYS_PINSTATERD) & (1<<22)) ? 0 : 1; // GPIO_22 is CF_DETECT
+
+	state->ready = 0;
+	state->vs_Xv = 0;
+	state->vs_3v = 0;
+	state->detect = 0;
+
+	if (inserted)
+	{
+		state->vs_3v=1;
+		state->detect = 1;
+		state->ready = 1;
+	}
+
+	state->bvd1=1;
+	state->bvd2=1;
+	state->wrprot=0; 
+	return 1;
+}
+
+
+static int hydrogen3_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+{
+
+	if(info->sock > PCMCIA_MAX_SOCK) return -1;
+
+	if(info->sock == 0)
+		info->irq = AU1000_GPIO_21;
+	else 
+		info->irq = -1;
+
+	return 0;
+}
+
+
+static int 
+hydrogen3_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+{
+	if(configure->sock > PCMCIA_MAX_SOCK) return -1;
+
+	au_sync_delay(300);
+
+	if (!configure->reset) {
+		// de-assert reset
+		writel(0x00010000, GPIO2_OUTPUT); // GPIO_200 CF_RESET
+		au_sync_delay(100);
+	}
+	else {
+		// assert reset
+		writel(0x00010001, GPIO2_OUTPUT); // GPIO_200 CF_RESET
+		au_sync_delay(300);
+	}
+	return 0;
+}
+
+struct pcmcia_low_level au1x00_pcmcia_ops = { 
+	hydrogen3_pcmcia_init,
+	hydrogen3_pcmcia_shutdown,
+	hydrogen3_pcmcia_socket_state,
+	hydrogen3_pcmcia_get_irq_info,
+	hydrogen3_pcmcia_configure_socket
+};
+
+struct pcmcia_low_level *
+hydrogen3_get_pcmcia_ops(void)
+{
+	return &au1x00_pcmcia_ops;
+};
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/pcmcia/au1000_pb1550.c linux-2.4.29-pre3/drivers/pcmcia/au1000_pb1550.c
--- linux-2.4.28/drivers/pcmcia/au1000_pb1550.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/drivers/pcmcia/au1000_pb1550.c	2004-12-22 16:05:54.988059872 +0000
@@ -0,0 +1,270 @@
+/*
+ *
+ * AMD Alchemy Pb1550 boards specific pcmcia routines.
+ *
+ * Copyright 2004 Embedded Edge LLC
+ *
+ * Based on au1000_pb1550.c:
+ * Copyright 2002 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *         	ppopov@mvista.com or source@mvista.com
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * 
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/tqueue.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/proc_fs.h>
+#include <linux/version.h>
+#include <linux/types.h>
+
+#include <pcmcia/version.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/ss.h>
+#include <pcmcia/bulkmem.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/bus_ops.h>
+#include "cs_internal.h"
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+#include <asm/au1000.h>
+#include <asm/au1000_pcmcia.h>
+
+#include <asm/pb1550.h>
+
+
+static int pb1550_pcmcia_init(struct pcmcia_init *init)
+{
+	bcsr->pcmcia = 0; /* turn off power */
+	au_sync_delay(2);
+	return PCMCIA_NUM_SOCKS;
+}
+
+static int pb1550_pcmcia_shutdown(void)
+{
+	bcsr->pcmcia = 0; /* turn off power */
+	au_sync_delay(2);
+	return 0;
+}
+
+static int 
+pb1550_pcmcia_socket_state(unsigned sock, struct pcmcia_state *state)
+{
+	u32 inserted;
+	u16 vs;
+
+	if(sock > PCMCIA_MAX_SOCK) return -1;
+
+	state->ready = 0;
+	state->vs_Xv = 0;
+	state->vs_3v = 0;
+	state->detect = 0;
+
+	if (sock == 0) {
+		vs = bcsr->status & BCSR_STATUS_PCMCIA0VS;
+		inserted = !(bcsr->status & (1<<4));
+	}
+	else {
+		vs = (bcsr->status & BCSR_STATUS_PCMCIA1VS)>>2;
+		inserted = !(bcsr->status & (1<<5));
+	}
+
+	DEBUG(KERN_DEBUG "pb1550 socket %d: inserted %d, vs %d\n", 
+			sock, inserted, vs, bcsr->status);
+
+	if (inserted) {
+		switch (vs) {
+			case 0:
+			case 2:
+				state->vs_3v=1;
+				break;
+			case 3: /* 5V */
+				break;
+			default:
+				/* return without setting 'detect' */
+				printk(KERN_ERR "pb1550 bad VS (%d)\n", vs);
+				return -1;
+		}
+		state->detect = 1;
+		state->ready = 1;
+	}
+	else {
+		/* if the card was previously inserted and then ejected,
+		 * we should turn off power to it
+		 */
+		if ((sock == 0) && (bcsr->pcmcia & BCSR_PCMCIA_PC0RST)) {
+			bcsr->pcmcia &= ~(BCSR_PCMCIA_PC0RST | 
+					BCSR_PCMCIA_PC0DRVEN |
+					BCSR_PCMCIA_PC0VPP |
+					BCSR_PCMCIA_PC0VCC);
+		}
+		else if ((sock == 1) && (bcsr->pcmcia & BCSR_PCMCIA_PC1RST)) {
+			bcsr->pcmcia &= ~(BCSR_PCMCIA_PC1RST | 
+					BCSR_PCMCIA_PC1DRVEN |
+					BCSR_PCMCIA_PC1VPP |
+					BCSR_PCMCIA_PC1VCC);
+		}
+	}
+
+	state->bvd1=1;
+	state->bvd2=1;
+	state->wrprot=0; 
+	return 1;
+}
+
+
+static int pb1550_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
+{
+	if(info->sock > PCMCIA_MAX_SOCK) return -1;
+
+	if(info->sock == 0) {
+		info->irq = AU1000_GPIO_0;
+	}
+	else 
+		info->irq = AU1000_GPIO_1;
+
+	return 0;
+}
+
+
+static int 
+pb1550_pcmcia_configure_socket(const struct pcmcia_configure *configure)
+{
+	u16 pwr;
+	int sock = configure->sock;
+
+	if(sock > PCMCIA_MAX_SOCK) return -1;
+
+	DEBUG(KERN_DEBUG "socket %d Vcc %dV Vpp %dV, reset %d\n", 
+			sock, configure->vcc, configure->vpp, configure->reset);
+
+	/* pcmcia reg was set to zero at init time. Be careful when
+	 * initializing a socket not to wipe out the settings of the 
+	 * other socket.
+	 */
+	pwr = bcsr->pcmcia;
+	pwr &= ~(0xf << sock*8); /* clear voltage settings */
+
+	switch(configure->vcc){
+		case 0:  /* Vcc 0 */
+			pwr |= SET_VCC_VPP(0,0,sock);
+			break;
+		case 50: /* Vcc 5V */
+			switch(configure->vpp) {
+				case 0:
+					pwr |= SET_VCC_VPP(2,0,sock);
+					break;
+				case 50:
+					pwr |= SET_VCC_VPP(2,1,sock);
+					break;
+				case 12:
+					pwr |= SET_VCC_VPP(2,2,sock);
+					break;
+				case 33:
+				default:
+					pwr |= SET_VCC_VPP(0,0,sock);
+					printk("%s: bad Vcc/Vpp (%d:%d)\n", 
+							__FUNCTION__, 
+							configure->vcc, 
+							configure->vpp);
+					break;
+			}
+			break;
+		case 33: /* Vcc 3.3V */
+			switch(configure->vpp) {
+				case 0:
+					pwr |= SET_VCC_VPP(1,0,sock);
+					break;
+				case 12:
+					pwr |= SET_VCC_VPP(1,2,sock);
+					break;
+				case 33:
+					pwr |= SET_VCC_VPP(1,1,sock);
+					break;
+				case 50:
+				default:
+					pwr |= SET_VCC_VPP(0,0,sock);
+					printk("%s: bad Vcc/Vpp (%d:%d)\n", 
+							__FUNCTION__, 
+							configure->vcc, 
+							configure->vpp);
+					break;
+			}
+			break;
+		default: /* what's this ? */
+			pwr |= SET_VCC_VPP(0,0,sock);
+			printk(KERN_ERR "%s: bad Vcc %d\n", 
+					__FUNCTION__, configure->vcc);
+			break;
+	}
+
+	bcsr->pcmcia = pwr;
+	au_sync_delay(500);
+
+	if (sock == 0) {
+		if (!configure->reset) {
+			pwr |= BCSR_PCMCIA_PC0DRVEN;
+			bcsr->pcmcia = pwr;
+			au_sync_delay(300);
+			pwr |= BCSR_PCMCIA_PC0RST;
+			bcsr->pcmcia = pwr;
+			au_sync_delay(100);
+		}
+		else {
+			pwr &= ~(BCSR_PCMCIA_PC0RST | BCSR_PCMCIA_PC0DRVEN);
+			bcsr->pcmcia = pwr;
+			au_sync_delay(100);
+		}
+	}
+	else {
+		if (!configure->reset) {
+			pwr |= BCSR_PCMCIA_PC1DRVEN;
+			bcsr->pcmcia = pwr;
+			au_sync_delay(300);
+			pwr |= BCSR_PCMCIA_PC1RST;
+			bcsr->pcmcia = pwr;
+			au_sync_delay(100);
+		}
+		else {
+			pwr &= ~(BCSR_PCMCIA_PC1RST | BCSR_PCMCIA_PC1DRVEN);
+			bcsr->pcmcia = pwr;
+			au_sync_delay(100);
+		}
+	}
+	return 0;
+}
+
+struct pcmcia_low_level au1x00_pcmcia_ops = { 
+	pb1550_pcmcia_init,
+	pb1550_pcmcia_shutdown,
+	pb1550_pcmcia_socket_state,
+	pb1550_pcmcia_get_irq_info,
+	pb1550_pcmcia_configure_socket
+};
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/pcmcia/au1000_pb1x00.c linux-2.4.29-pre3/drivers/pcmcia/au1000_pb1x00.c
--- linux-2.4.28/drivers/pcmcia/au1000_pb1x00.c	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-pre3/drivers/pcmcia/au1000_pb1x00.c	2004-12-22 16:07:18.920300232 +0000
@@ -408,7 +408,7 @@ pb1x00_pcmcia_configure_socket(const str
 }
 
 
-struct pcmcia_low_level pb1x00_pcmcia_ops = { 
+struct pcmcia_low_level au1x00_pcmcia_ops = { 
 	pb1x00_pcmcia_init,
 	pb1x00_pcmcia_shutdown,
 	pb1x00_pcmcia_socket_state,
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/pcmcia/au1000_xxs1500.c linux-2.4.29-pre3/drivers/pcmcia/au1000_xxs1500.c
--- linux-2.4.28/drivers/pcmcia/au1000_xxs1500.c	2003-08-25 11:44:42.000000000 +0000
+++ linux-2.4.29-pre3/drivers/pcmcia/au1000_xxs1500.c	2004-12-22 16:06:57.637535704 +0000
@@ -92,7 +92,7 @@ xxs1500_pcmcia_socket_state(unsigned soc
 	gpio = au_readl(SYS_PINSTATERD);
 	gpio2 = au_readl(GPIO2_PINSTATE);
 
-	vs = gpio2 & ((1<<8) | (1<<9));
+	vs = (gpio2 >> 8) & 0x3;
 	inserted = (!(gpio & 0x1) && !(gpio & 0x2));
 
 	state->ready = 0;
@@ -110,8 +110,7 @@ xxs1500_pcmcia_socket_state(unsigned soc
 			case 3: /* 5V */
 			default:
 				/* return without setting 'detect' */
-				printk(KERN_ERR "au1x00_cs: unsupported VS\n",
-						vs);
+				printk(KERN_ERR "au1x00_cs: bad VS %d\n", vs);
 				return;
 		}
 		state->detect = 1;
@@ -156,7 +155,8 @@ xxs1500_pcmcia_configure_socket(const st
 			break;
 		case 50: /* Vcc 5V */
 		default: /* what's this ? */
-			printk(KERN_ERR "au1x00_cs: unsupported VCC\n");
+			printk(KERN_ERR "au1x00_cs: bad VCC %d\n", 
+					configure->vcc);
 		case 0:  /* Vcc 0 */
 			/* turn off power */
 			au_sync_delay(100);
@@ -182,7 +182,7 @@ xxs1500_pcmcia_configure_socket(const st
 	return 0;
 }
 
-struct pcmcia_low_level xxs1500_pcmcia_ops = { 
+struct pcmcia_low_level au1x00_pcmcia_ops = { 
 	xxs1500_pcmcia_init,
 	xxs1500_pcmcia_shutdown,
 	xxs1500_pcmcia_socket_state,
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/pcmcia/ricoh.h linux-2.4.29-pre3/drivers/pcmcia/ricoh.h
--- linux-2.4.28/drivers/pcmcia/ricoh.h	2003-06-13 14:51:35.000000000 +0000
+++ linux-2.4.29-pre3/drivers/pcmcia/ricoh.h	2004-12-22 16:06:39.366313352 +0000
@@ -109,7 +109,7 @@
 
 /* 16-bit IO and memory timing registers */
 #define RL5C4XX_16BIT_IO_0		0x0088	/* 16 bit */
-#define RL5C4XX_16BIT_MEM_0		0x0088	/* 16 bit */
+#define RL5C4XX_16BIT_MEM_0		0x008a	/* 16 bit */
 #define  RL5C4XX_SETUP_MASK		0x0007
 #define  RL5C4XX_SETUP_SHIFT		0
 #define  RL5C4XX_CMD_MASK		0x01f0
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/s390/char/con3215.c linux-2.4.29-pre3/drivers/s390/char/con3215.c
--- linux-2.4.28/drivers/s390/char/con3215.c	2003-08-25 11:44:42.000000000 +0000
+++ linux-2.4.29-pre3/drivers/s390/char/con3215.c	2004-12-22 16:07:11.994353136 +0000
@@ -363,10 +363,7 @@ static void raw3215_softint(void *data)
 	tty = raw->tty;
 	if (tty != NULL &&
 	    RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup)(tty);
-		wake_up_interruptible(&tty->write_wait);
+		tty_wakeup(tty);
 	}
 }
 
@@ -978,10 +975,7 @@ static void tty3215_flush_buffer(struct 
 
 	raw = (raw3215_info *) tty->driver_data;
 	raw3215_flush_buffer(raw);
-	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
+	tty_wakeup(tty);
 }
 
 /*
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/s390/char/tubtty.c linux-2.4.29-pre3/drivers/s390/char/tubtty.c
--- linux-2.4.28/drivers/s390/char/tubtty.c	2002-11-28 23:53:14.000000000 +0000
+++ linux-2.4.29-pre3/drivers/s390/char/tubtty.c	2004-12-22 16:07:22.617738136 +0000
@@ -445,10 +445,7 @@ tty3270_flush_buffer(struct tty_struct *
 		ob->bc_cnt = 0;
 		TUBUNLOCK(tubp->irq, flags);
 	}
-	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
+	tty_wakeup(tty);
 }
 
 static int
@@ -646,10 +643,7 @@ tty3270_bh(void *data)
 	}
 
 	if (tty != NULL) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup != NULL)
-			(tty->ldisc.write_wakeup)(tty);
-		wake_up_interruptible(&tty->write_wait);
+		tty_wakeup(tty);
 	}
 do_unlock:
 	TUBUNLOCK(tubp->irq, flags);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/s390/net/ctctty.c linux-2.4.29-pre3/drivers/s390/net/ctctty.c
--- linux-2.4.28/drivers/s390/net/ctctty.c	2003-11-28 18:26:20.000000000 +0000
+++ linux-2.4.29-pre3/drivers/s390/net/ctctty.c	2004-12-22 16:06:56.197754584 +0000
@@ -362,9 +362,8 @@ ctc_tty_tint(ctc_tty_info * info)
 
 		info->flags &= ~CTC_ASYNC_TX_LINESTAT;
 		if (tty) {
-			if (wake && (tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-			    tty->ldisc.write_wakeup)
-				(tty->ldisc.write_wakeup)(tty);
+			if (wake)
+				tty_wakeup(tty);
 			wake_up_interruptible(&tty->write_wait);
 		}
 	}
@@ -655,10 +654,7 @@ ctc_tty_flush_buffer(struct tty_struct *
 	skb_queue_purge(&info->tx_queue);
 	info->lsr |= UART_LSR_TEMT;
 	restore_flags(flags);
-	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup) (tty);
+	tty_wakeup(tty);
 }
 
 static void
@@ -1168,8 +1164,7 @@ ctc_tty_close(struct tty_struct *tty, st
 	ctc_tty_shutdown(info);
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	tty_ldisc_flush(tty);
 	spin_lock_irqsave(&ctc_tty_lock, saveflags);
 	info->tty = 0;
 	spin_unlock_irqrestore(&ctc_tty_lock, saveflags);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/sbus/char/aurora.c linux-2.4.29-pre3/drivers/sbus/char/aurora.c
--- linux-2.4.28/drivers/sbus/char/aurora.c	2002-11-28 23:53:14.000000000 +0000
+++ linux-2.4.29-pre3/drivers/sbus/char/aurora.c	2004-12-22 16:05:50.376760896 +0000
@@ -1573,8 +1573,7 @@ static void aurora_close(struct tty_stru
 	aurora_shutdown_port(bp, port);
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	tty_ldisc_flush(tty);
 	tty->closing = 0;
 	port->event = 0;
 	port->tty = 0;
@@ -1785,11 +1784,8 @@ static void aurora_flush_buffer(struct t
 	save_flags(flags); cli();
 	port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
 	restore_flags(flags);
-	
-	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
+
+	tty_wakeup(tty);	
 #ifdef AURORA_DEBUG
 	printk("aurora_flush_buffer: end\n");
 #endif
@@ -2286,10 +2282,7 @@ static void do_softint(void *private_)
 		return;
 
 	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup)(tty);
-		wake_up_interruptible(&tty->write_wait);
+		tty_wakeup(tty);
 	}
 #ifdef AURORA_DEBUG
 	printk("do_softint: end\n");
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/sbus/char/sab82532.c linux-2.4.29-pre3/drivers/sbus/char/sab82532.c
--- linux-2.4.28/drivers/sbus/char/sab82532.c	2002-08-03 00:39:44.000000000 +0000
+++ linux-2.4.29-pre3/drivers/sbus/char/sab82532.c	2004-12-22 16:06:26.567259104 +0000
@@ -669,10 +669,7 @@ static void do_softint(void *private_)
 		return;
 
 	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup)(tty);
-		wake_up_interruptible(&tty->write_wait);
+		tty_wakeup(tty);
 	}
 }
 
@@ -1206,10 +1203,7 @@ static void sab82532_flush_buffer(struct
 	info->xmit.head = info->xmit.tail = 0;
 	restore_flags(flags);
 
-	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
+	tty_wakeup(tty);
 }
 
 /*
@@ -1667,8 +1661,7 @@ static void sab82532_close(struct tty_st
 	shutdown(info);
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	tty_ldisc_flush(tty);
 	tty->closing = 0;
 	info->event = 0;
 	info->tty = 0;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/sbus/char/su.c linux-2.4.29-pre3/drivers/sbus/char/su.c
--- linux-2.4.28/drivers/sbus/char/su.c	2002-08-03 00:39:44.000000000 +0000
+++ linux-2.4.29-pre3/drivers/sbus/char/su.c	2004-12-22 16:05:55.653958640 +0000
@@ -698,10 +698,7 @@ static void do_softint(void *private_)
 		return;
 
 	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup)(tty);
-		wake_up_interruptible(&tty->write_wait);
+		tty_wakeup(tty);
 	}
 }
 
@@ -1313,10 +1310,7 @@ su_flush_buffer(struct tty_struct *tty)
 	save_flags(flags); cli();
 	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
 	restore_flags(flags);
-	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
+	tty_wakeup(tty);
 }
 
 /*
@@ -1815,8 +1809,7 @@ su_close(struct tty_struct *tty, struct 
 	shutdown(info);
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	tty_ldisc_flush(tty);
 	tty->closing = 0;
 	info->event = 0;
 	info->tty = 0;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/sbus/char/zs.c linux-2.4.29-pre3/drivers/sbus/char/zs.c
--- linux-2.4.28/drivers/sbus/char/zs.c	2002-08-03 00:39:44.000000000 +0000
+++ linux-2.4.29-pre3/drivers/sbus/char/zs.c	2004-12-22 16:07:54.965820480 +0000
@@ -746,10 +746,7 @@ static void do_softint(void *private_)
 		return;
 
 	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup)(tty);
-		wake_up_interruptible(&tty->write_wait);
+		tty_wakeup(tty);
 	}
 }
 
@@ -1199,10 +1196,7 @@ static void zs_flush_buffer(struct tty_s
 	cli();
 	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
 	sti();
-	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
+	tty_wakeup(tty);
 }
 
 /*
@@ -1600,15 +1594,14 @@ static void zs_close(struct tty_struct *
 	shutdown(info);
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	tty_ldisc_flush(tty);
 	tty->closing = 0;
 	info->event = 0;
 	info->tty = 0;
-	if (tty->ldisc.num != ldiscs[N_TTY].num) {
+	if (tty->ldisc.num != N_TTY) {
 		if (tty->ldisc.close)
 			(tty->ldisc.close)(tty);
-		tty->ldisc = ldiscs[N_TTY];
+		tty->ldisc = *(tty_ldisc_get(N_TTY));
 		tty->termios->c_line = N_TTY;
 		if (tty->ldisc.open)
 			(tty->ldisc.open)(tty);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/scsi/Config.in linux-2.4.29-pre3/drivers/scsi/Config.in
--- linux-2.4.28/drivers/scsi/Config.in	2004-12-22 16:17:18.161201768 +0000
+++ linux-2.4.29-pre3/drivers/scsi/Config.in	2004-12-22 16:06:32.715324456 +0000
@@ -69,9 +69,10 @@ dep_tristate 'AM53/79C974 PCI SCSI suppo
 dep_tristate 'AMI MegaRAID support' CONFIG_SCSI_MEGARAID $CONFIG_SCSI
 dep_tristate 'AMI MegaRAID2 support' CONFIG_SCSI_MEGARAID2 $CONFIG_SCSI
 dep_mbool 'Serial ATA (SATA) support' CONFIG_SCSI_SATA $CONFIG_SCSI
+dep_tristate '  AHCI SATA support (EXPERIMENTAL)' CONFIG_SCSI_SATA_AHCI $CONFIG_SCSI_SATA $CONFIG_PCI $CONFIG_EXPERIMENTAL
 dep_tristate '  ServerWorks Frodo / Apple K2 SATA support (EXPERIMENTAL)' CONFIG_SCSI_SATA_SVW $CONFIG_SCSI_SATA $CONFIG_PCI $CONFIG_EXPERIMENTAL
 dep_tristate '  Intel PIIX/ICH SATA support' CONFIG_SCSI_ATA_PIIX $CONFIG_SCSI_SATA $CONFIG_PCI
-dep_tristate '  NVIDIA SATA support (EXPERIMENTAL)' CONFIG_SCSI_SATA_NV $CONFIG_SCSI_SATA $CONFIG_PCI
+dep_tristate '  NVIDIA SATA support (EXPERIMENTAL)' CONFIG_SCSI_SATA_NV $CONFIG_SCSI_SATA $CONFIG_PCI $CONFIG_EXPERIMENTAL
 dep_tristate '  Promise SATA TX2/TX4 support (EXPERIMENTAL)' CONFIG_SCSI_SATA_PROMISE $CONFIG_SCSI_SATA $CONFIG_PCI $CONFIG_EXPERIMENTAL
 dep_tristate '  Promise SATA SX4 support (EXPERIMENTAL)' CONFIG_SCSI_SATA_SX4 $CONFIG_SCSI_SATA $CONFIG_PCI $CONFIG_EXPERIMENTAL
 dep_tristate '  Silicon Image SATA support (EXPERIMENTAL)' CONFIG_SCSI_SATA_SIL $CONFIG_SCSI_SATA $CONFIG_PCI $CONFIG_EXPERIMENTAL
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/scsi/Makefile linux-2.4.29-pre3/drivers/scsi/Makefile
--- linux-2.4.28/drivers/scsi/Makefile	2004-12-22 16:17:18.161201768 +0000
+++ linux-2.4.29-pre3/drivers/scsi/Makefile	2004-12-22 16:07:22.446764128 +0000
@@ -130,6 +130,7 @@ obj-$(CONFIG_SCSI_FCAL)		+= fcal.o
 obj-$(CONFIG_SCSI_CPQFCTS)	+= cpqfc.o
 obj-$(CONFIG_SCSI_LASI700)	+= lasi700.o 53c700.o
 obj-$(CONFIG_SCSI_NSP32)	+= nsp32.o
+obj-$(CONFIG_SCSI_SATA_AHCI)	+= libata.o ahci.o
 obj-$(CONFIG_SCSI_SATA_SVW)	+= libata.o sata_svw.o
 obj-$(CONFIG_SCSI_ATA_PIIX)	+= libata.o ata_piix.o
 obj-$(CONFIG_SCSI_SATA_PROMISE)	+= libata.o sata_promise.o
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/scsi/aacraid/README linux-2.4.29-pre3/drivers/scsi/aacraid/README
--- linux-2.4.28/drivers/scsi/aacraid/README	2003-08-25 11:44:42.000000000 +0000
+++ linux-2.4.29-pre3/drivers/scsi/aacraid/README	2004-12-22 16:05:43.151859248 +0000
@@ -30,7 +30,7 @@ People
 Alan Cox <alan@redhat.com>
 Christoph Hellwig <hch@infradead.org>	(small cleanups/fixes)
 Matt Domsch <matt_domsch@dell.com>	(revision ioctl, adapter messages)
-Deanna Bonds <deanna_bonds@adaptec.com> (non-DASD support, PAE fibs and 64 bit, added new adaptec controllers
+Deanna Bonds                            (non-DASD support, PAE fibs and 64 bit, added new adaptec controllers
 					 added new ioctls, changed scsi interface to use new error handler,
 					 increased the number of fibs and outstanding commands to a container)
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/scsi/advansys.c linux-2.4.29-pre3/drivers/scsi/advansys.c
--- linux-2.4.28/drivers/scsi/advansys.c	2004-12-22 16:17:18.213193864 +0000
+++ linux-2.4.29-pre3/drivers/scsi/advansys.c	2004-12-22 16:06:15.392957856 +0000
@@ -713,7 +713,7 @@
      Tom Rini <trini@kernel.crashing.org> provided the CONFIG_ISA
      patch and helped with PowerPC wide and narrow board support.
 
-     Philip Blundell <philip.blundell@pobox.com> provided an
+     Philip Blundell <philb@gnu.org> provided an
      advansys_interrupts_enabled patch.
 
      Dave Jones <dave@denial.force9.co.uk> reported the compiler
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/scsi/ahci.c linux-2.4.29-pre3/drivers/scsi/ahci.c
--- linux-2.4.28/drivers/scsi/ahci.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/drivers/scsi/ahci.c	2004-12-22 16:07:45.356281352 +0000
@@ -0,0 +1,1041 @@
+/*
+ *  ahci.c - AHCI SATA support
+ *
+ *  Copyright 2004 Red Hat, Inc.
+ *
+ *  The contents of this file are subject to the Open
+ *  Software License version 1.1 that can be found at
+ *  http://www.opensource.org/licenses/osl-1.1.txt and is included herein
+ *  by reference.
+ *
+ *  Alternatively, the contents of this file may be used under the terms
+ *  of the GNU General Public License version 2 (the "GPL") as distributed
+ *  in the kernel source COPYING file, in which case the provisions of
+ *  the GPL are applicable instead of the above.  If you wish to allow
+ *  the use of your version of this file only under the terms of the
+ *  GPL and not to allow others to use your version of this file under
+ *  the OSL, indicate your decision by deleting the provisions above and
+ *  replace them with the notice and other provisions required by the GPL.
+ *  If you do not delete the provisions above, a recipient may use your
+ *  version of this file under either the OSL or the GPL.
+ *
+ * Version 1.0 of the AHCI specification:
+ * http://www.intel.com/technology/serialata/pdf/rev1_0.pdf
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include "scsi.h"
+#include <scsi/scsi_host.h>
+#include <linux/libata.h>
+#include <asm/io.h>
+
+#define DRV_NAME	"ahci"
+#define DRV_VERSION	"1.00"
+
+#define msleep libata_msleep   /* 2.4-specific */
+
+enum {
+	AHCI_PCI_BAR		= 5,
+	AHCI_MAX_SG		= 168, /* hardware max is 64K */
+	AHCI_DMA_BOUNDARY	= 0xffffffff,
+	AHCI_USE_CLUSTERING	= 0,
+	AHCI_CMD_SLOT_SZ	= 32 * 32,
+	AHCI_RX_FIS_SZ		= 256,
+	AHCI_CMD_TBL_HDR	= 0x80,
+	AHCI_CMD_TBL_SZ		= AHCI_CMD_TBL_HDR + (AHCI_MAX_SG * 16),
+	AHCI_PORT_PRIV_DMA_SZ	= AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_SZ +
+				  AHCI_RX_FIS_SZ,
+	AHCI_IRQ_ON_SG		= (1 << 31),
+	AHCI_CMD_ATAPI		= (1 << 5),
+	AHCI_CMD_WRITE		= (1 << 6),
+
+	RX_FIS_D2H_REG		= 0x40,	/* offset of D2H Register FIS data */
+
+	board_ahci		= 0,
+
+	/* global controller registers */
+	HOST_CAP		= 0x00, /* host capabilities */
+	HOST_CTL		= 0x04, /* global host control */
+	HOST_IRQ_STAT		= 0x08, /* interrupt status */
+	HOST_PORTS_IMPL		= 0x0c, /* bitmap of implemented ports */
+	HOST_VERSION		= 0x10, /* AHCI spec. version compliancy */
+
+	/* HOST_CTL bits */
+	HOST_RESET		= (1 << 0),  /* reset controller; self-clear */
+	HOST_IRQ_EN		= (1 << 1),  /* global IRQ enable */
+	HOST_AHCI_EN		= (1 << 31), /* AHCI enabled */
+
+	/* HOST_CAP bits */
+	HOST_CAP_64		= (1 << 31), /* PCI DAC (64-bit DMA) support */
+
+	/* registers for each SATA port */
+	PORT_LST_ADDR		= 0x00, /* command list DMA addr */
+	PORT_LST_ADDR_HI	= 0x04, /* command list DMA addr hi */
+	PORT_FIS_ADDR		= 0x08, /* FIS rx buf addr */
+	PORT_FIS_ADDR_HI	= 0x0c, /* FIS rx buf addr hi */
+	PORT_IRQ_STAT		= 0x10, /* interrupt status */
+	PORT_IRQ_MASK		= 0x14, /* interrupt enable/disable mask */
+	PORT_CMD		= 0x18, /* port command */
+	PORT_TFDATA		= 0x20,	/* taskfile data */
+	PORT_SIG		= 0x24,	/* device TF signature */
+	PORT_CMD_ISSUE		= 0x38, /* command issue */
+	PORT_SCR		= 0x28, /* SATA phy register block */
+	PORT_SCR_STAT		= 0x28, /* SATA phy register: SStatus */
+	PORT_SCR_CTL		= 0x2c, /* SATA phy register: SControl */
+	PORT_SCR_ERR		= 0x30, /* SATA phy register: SError */
+	PORT_SCR_ACT		= 0x34, /* SATA phy register: SActive */
+
+	/* PORT_IRQ_{STAT,MASK} bits */
+	PORT_IRQ_COLD_PRES	= (1 << 31), /* cold presence detect */
+	PORT_IRQ_TF_ERR		= (1 << 30), /* task file error */
+	PORT_IRQ_HBUS_ERR	= (1 << 29), /* host bus fatal error */
+	PORT_IRQ_HBUS_DATA_ERR	= (1 << 28), /* host bus data error */
+	PORT_IRQ_IF_ERR		= (1 << 27), /* interface fatal error */
+	PORT_IRQ_IF_NONFATAL	= (1 << 26), /* interface non-fatal error */
+	PORT_IRQ_OVERFLOW	= (1 << 24), /* xfer exhausted available S/G */
+	PORT_IRQ_BAD_PMP	= (1 << 23), /* incorrect port multiplier */
+
+	PORT_IRQ_PHYRDY		= (1 << 22), /* PhyRdy changed */
+	PORT_IRQ_DEV_ILCK	= (1 << 7), /* device interlock */
+	PORT_IRQ_CONNECT	= (1 << 6), /* port connect change status */
+	PORT_IRQ_SG_DONE	= (1 << 5), /* descriptor processed */
+	PORT_IRQ_UNK_FIS	= (1 << 4), /* unknown FIS rx'd */
+	PORT_IRQ_SDB_FIS	= (1 << 3), /* Set Device Bits FIS rx'd */
+	PORT_IRQ_DMAS_FIS	= (1 << 2), /* DMA Setup FIS rx'd */
+	PORT_IRQ_PIOS_FIS	= (1 << 1), /* PIO Setup FIS rx'd */
+	PORT_IRQ_D2H_REG_FIS	= (1 << 0), /* D2H Register FIS rx'd */
+
+	PORT_IRQ_FATAL		= PORT_IRQ_TF_ERR |
+				  PORT_IRQ_HBUS_ERR |
+				  PORT_IRQ_HBUS_DATA_ERR |
+				  PORT_IRQ_IF_ERR,
+	DEF_PORT_IRQ		= PORT_IRQ_FATAL | PORT_IRQ_PHYRDY |
+				  PORT_IRQ_CONNECT | PORT_IRQ_SG_DONE |
+				  PORT_IRQ_UNK_FIS | PORT_IRQ_SDB_FIS |
+				  PORT_IRQ_DMAS_FIS | PORT_IRQ_PIOS_FIS |
+				  PORT_IRQ_D2H_REG_FIS,
+
+	/* PORT_CMD bits */
+	PORT_CMD_LIST_ON	= (1 << 15), /* cmd list DMA engine running */
+	PORT_CMD_FIS_ON		= (1 << 14), /* FIS DMA engine running */
+	PORT_CMD_FIS_RX		= (1 << 4), /* Enable FIS receive DMA engine */
+	PORT_CMD_POWER_ON	= (1 << 2), /* Power up device */
+	PORT_CMD_SPIN_UP	= (1 << 1), /* Spin up device */
+	PORT_CMD_START		= (1 << 0), /* Enable port DMA engine */
+
+	PORT_CMD_ICC_ACTIVE	= (0x1 << 28), /* Put i/f in active state */
+	PORT_CMD_ICC_PARTIAL	= (0x2 << 28), /* Put i/f in partial state */
+	PORT_CMD_ICC_SLUMBER	= (0x6 << 28), /* Put i/f in slumber state */
+};
+
+struct ahci_cmd_hdr {
+	u32			opts;
+	u32			status;
+	u32			tbl_addr;
+	u32			tbl_addr_hi;
+	u32			reserved[4];
+};
+
+struct ahci_sg {
+	u32			addr;
+	u32			addr_hi;
+	u32			reserved;
+	u32			flags_size;
+};
+
+struct ahci_host_priv {
+	unsigned long		flags;
+	u32			cap;	/* cache of HOST_CAP register */
+	u32			port_map; /* cache of HOST_PORTS_IMPL reg */
+};
+
+struct ahci_port_priv {
+	struct ahci_cmd_hdr	*cmd_slot;
+	dma_addr_t		cmd_slot_dma;
+	void			*cmd_tbl;
+	dma_addr_t		cmd_tbl_dma;
+	struct ahci_sg		*cmd_tbl_sg;
+	void			*rx_fis;
+	dma_addr_t		rx_fis_dma;
+};
+
+static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg);
+static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
+static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
+static int ahci_qc_issue(struct ata_queued_cmd *qc);
+static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
+static void ahci_phy_reset(struct ata_port *ap);
+static void ahci_irq_clear(struct ata_port *ap);
+static void ahci_eng_timeout(struct ata_port *ap);
+static int ahci_port_start(struct ata_port *ap);
+static void ahci_port_stop(struct ata_port *ap);
+static void ahci_host_stop(struct ata_host_set *host_set);
+static void ahci_qc_prep(struct ata_queued_cmd *qc);
+static u8 ahci_check_status(struct ata_port *ap);
+static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
+
+static Scsi_Host_Template ahci_sht = {
+	.module			= THIS_MODULE,
+	.name			= DRV_NAME,
+	.ioctl			= ata_scsi_ioctl,
+	.detect			= ata_scsi_detect,
+	.release		= ata_scsi_release,
+	.queuecommand		= ata_scsi_queuecmd,
+	.eh_strategy_handler	= ata_scsi_error,
+	.can_queue		= ATA_DEF_QUEUE,
+	.this_id		= ATA_SHT_THIS_ID,
+	.sg_tablesize		= AHCI_MAX_SG,
+	.max_sectors		= ATA_MAX_SECTORS,
+	.cmd_per_lun		= ATA_SHT_CMD_PER_LUN,
+	.use_new_eh_code	= ATA_SHT_NEW_EH_CODE,
+	.emulated		= ATA_SHT_EMULATED,
+	.use_clustering		= AHCI_USE_CLUSTERING,
+	.proc_name		= DRV_NAME,
+	.bios_param		= ata_std_bios_param,
+};
+
+static struct ata_port_operations ahci_ops = {
+	.port_disable		= ata_port_disable,
+
+	.check_status		= ahci_check_status,
+	.dev_select		= ata_noop_dev_select,
+
+	.phy_reset		= ahci_phy_reset,
+
+	.qc_prep		= ahci_qc_prep,
+	.qc_issue		= ahci_qc_issue,
+
+	.eng_timeout		= ahci_eng_timeout,
+
+	.irq_handler		= ahci_interrupt,
+	.irq_clear		= ahci_irq_clear,
+
+	.scr_read		= ahci_scr_read,
+	.scr_write		= ahci_scr_write,
+
+	.port_start		= ahci_port_start,
+	.port_stop		= ahci_port_stop,
+	.host_stop		= ahci_host_stop,
+};
+
+static struct ata_port_info ahci_port_info[] = {
+	/* board_ahci */
+	{
+		.sht		= &ahci_sht,
+		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+				  ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
+				  ATA_FLAG_PIO_DMA,
+		.pio_mask	= 0x03, /* pio3-4 */
+		.udma_mask	= 0x7f, /* udma0-6 ; FIXME */
+		.port_ops	= &ahci_ops,
+	},
+};
+
+static struct pci_device_id ahci_pci_tbl[] = {
+	{ PCI_VENDOR_ID_INTEL, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	  board_ahci },
+	{ PCI_VENDOR_ID_INTEL, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+	  board_ahci },
+	{ }	/* terminate list */
+};
+
+
+static struct pci_driver ahci_pci_driver = {
+	.name			= DRV_NAME,
+	.id_table		= ahci_pci_tbl,
+	.probe			= ahci_init_one,
+	.remove			= ata_pci_remove_one,
+};
+
+
+static inline unsigned long ahci_port_base_ul (unsigned long base, unsigned int port)
+{
+	return base + 0x100 + (port * 0x80);
+}
+
+static inline void *ahci_port_base (void *base, unsigned int port)
+{
+	return (void *) ahci_port_base_ul((unsigned long)base, port);
+}
+
+static void ahci_host_stop(struct ata_host_set *host_set)
+{
+	struct ahci_host_priv *hpriv = host_set->private_data;
+	kfree(hpriv);
+}
+
+static int ahci_port_start(struct ata_port *ap)
+{
+	struct device *dev = ap->host_set->dev;
+	struct ahci_host_priv *hpriv = ap->host_set->private_data;
+	struct ahci_port_priv *pp;
+	int rc;
+	void *mem, *mmio = ap->host_set->mmio_base;
+	void *port_mmio = ahci_port_base(mmio, ap->port_no);
+	dma_addr_t mem_dma;
+
+	rc = ata_port_start(ap);
+	if (rc)
+		return rc;
+
+	pp = kmalloc(sizeof(*pp), GFP_KERNEL);
+	if (!pp) {
+		rc = -ENOMEM;
+		goto err_out;
+	}
+	memset(pp, 0, sizeof(*pp));
+
+	mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL);
+	if (!mem) {
+		rc = -ENOMEM;
+		goto err_out_kfree;
+	}
+	memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ);
+
+	/*
+	 * First item in chunk of DMA memory: 32-slot command table,
+	 * 32 bytes each in size
+	 */
+	pp->cmd_slot = mem;
+	pp->cmd_slot_dma = mem_dma;
+
+	mem += AHCI_CMD_SLOT_SZ;
+	mem_dma += AHCI_CMD_SLOT_SZ;
+
+	/*
+	 * Second item: Received-FIS area
+	 */
+	pp->rx_fis = mem;
+	pp->rx_fis_dma = mem_dma;
+
+	mem += AHCI_RX_FIS_SZ;
+	mem_dma += AHCI_RX_FIS_SZ;
+
+	/*
+	 * Third item: data area for storing a single command
+	 * and its scatter-gather table
+	 */
+	pp->cmd_tbl = mem;
+	pp->cmd_tbl_dma = mem_dma;
+
+	pp->cmd_tbl_sg = mem + AHCI_CMD_TBL_HDR;
+
+	ap->private_data = pp;
+
+	if (hpriv->cap & HOST_CAP_64)
+		writel((pp->cmd_slot_dma >> 16) >> 16, port_mmio + PORT_LST_ADDR_HI);
+	writel(pp->cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR);
+	readl(port_mmio + PORT_LST_ADDR); /* flush */
+
+	if (hpriv->cap & HOST_CAP_64)
+		writel((pp->rx_fis_dma >> 16) >> 16, port_mmio + PORT_FIS_ADDR_HI);
+	writel(pp->rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR);
+	readl(port_mmio + PORT_FIS_ADDR); /* flush */
+
+	writel(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX |
+	       PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP |
+	       PORT_CMD_START, port_mmio + PORT_CMD);
+	readl(port_mmio + PORT_CMD); /* flush */
+
+	return 0;
+
+err_out_kfree:
+	kfree(pp);
+err_out:
+	ata_port_stop(ap);
+	return rc;
+}
+
+
+static void ahci_port_stop(struct ata_port *ap)
+{
+	struct device *dev = ap->host_set->dev;
+	struct ahci_port_priv *pp = ap->private_data;
+	void *mmio = ap->host_set->mmio_base;
+	void *port_mmio = ahci_port_base(mmio, ap->port_no);
+	u32 tmp;
+
+	tmp = readl(port_mmio + PORT_CMD);
+	tmp &= ~(PORT_CMD_START | PORT_CMD_FIS_RX);
+	writel(tmp, port_mmio + PORT_CMD);
+	readl(port_mmio + PORT_CMD); /* flush */
+
+	/* spec says 500 msecs for each PORT_CMD_{START,FIS_RX} bit, so
+	 * this is slightly incorrect.
+	 */
+	msleep(500);
+
+	ap->private_data = NULL;
+	dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ,
+			  pp->cmd_slot, pp->cmd_slot_dma);
+	kfree(pp);
+	ata_port_stop(ap);
+}
+
+static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in)
+{
+	unsigned int sc_reg;
+
+	switch (sc_reg_in) {
+	case SCR_STATUS:	sc_reg = 0; break;
+	case SCR_CONTROL:	sc_reg = 1; break;
+	case SCR_ERROR:		sc_reg = 2; break;
+	case SCR_ACTIVE:	sc_reg = 3; break;
+	default:
+		return 0xffffffffU;
+	}
+
+	return readl((void *) ap->ioaddr.scr_addr + (sc_reg * 4));
+}
+
+
+static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg_in,
+			       u32 val)
+{
+	unsigned int sc_reg;
+
+	switch (sc_reg_in) {
+	case SCR_STATUS:	sc_reg = 0; break;
+	case SCR_CONTROL:	sc_reg = 1; break;
+	case SCR_ERROR:		sc_reg = 2; break;
+	case SCR_ACTIVE:	sc_reg = 3; break;
+	default:
+		return;
+	}
+
+	writel(val, (void *) ap->ioaddr.scr_addr + (sc_reg * 4));
+}
+
+static void ahci_phy_reset(struct ata_port *ap)
+{
+	void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
+	struct ata_taskfile tf;
+	struct ata_device *dev = &ap->device[0];
+	u32 tmp;
+
+	__sata_phy_reset(ap);
+
+	if (ap->flags & ATA_FLAG_PORT_DISABLED)
+		return;
+
+	tmp = readl(port_mmio + PORT_SIG);
+	tf.lbah		= (tmp >> 24)	& 0xff;
+	tf.lbam		= (tmp >> 16)	& 0xff;
+	tf.lbal		= (tmp >> 8)	& 0xff;
+	tf.nsect	= (tmp)		& 0xff;
+
+	dev->class = ata_dev_classify(&tf);
+	if (!ata_dev_present(dev))
+		ata_port_disable(ap);
+}
+
+static u8 ahci_check_status(struct ata_port *ap)
+{
+	void *mmio = (void *) ap->ioaddr.cmd_addr;
+
+	return readl(mmio + PORT_TFDATA) & 0xFF;
+}
+
+static void ahci_fill_sg(struct ata_queued_cmd *qc)
+{
+	struct ahci_port_priv *pp = qc->ap->private_data;
+	unsigned int i;
+
+	VPRINTK("ENTER\n");
+
+	/*
+	 * Next, the S/G list.
+	 */
+	for (i = 0; i < qc->n_elem; i++) {
+		u32 sg_len;
+		dma_addr_t addr;
+
+		addr = sg_dma_address(&qc->sg[i]);
+		sg_len = sg_dma_len(&qc->sg[i]);
+
+		pp->cmd_tbl_sg[i].addr = cpu_to_le32(addr & 0xffffffff);
+		pp->cmd_tbl_sg[i].addr_hi = cpu_to_le32((addr >> 16) >> 16);
+		pp->cmd_tbl_sg[i].flags_size = cpu_to_le32(sg_len - 1);
+	}
+}
+
+static void ahci_qc_prep(struct ata_queued_cmd *qc)
+{
+	struct ahci_port_priv *pp = qc->ap->private_data;
+	u32 opts;
+	const u32 cmd_fis_len = 5; /* five dwords */
+
+	/*
+	 * Fill in command slot information (currently only one slot,
+	 * slot 0, is currently since we don't do queueing)
+	 */
+
+	opts = (qc->n_elem << 16) | cmd_fis_len;
+	if (qc->tf.flags & ATA_TFLAG_WRITE)
+		opts |= AHCI_CMD_WRITE;
+
+	switch (qc->tf.protocol) {
+	case ATA_PROT_ATAPI:
+	case ATA_PROT_ATAPI_NODATA:
+	case ATA_PROT_ATAPI_DMA:
+		opts |= AHCI_CMD_ATAPI;
+		break;
+
+	default:
+		/* do nothing */
+		break;
+	}
+
+	pp->cmd_slot[0].opts = cpu_to_le32(opts);
+	pp->cmd_slot[0].status = 0;
+	pp->cmd_slot[0].tbl_addr = cpu_to_le32(pp->cmd_tbl_dma & 0xffffffff);
+	pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16);
+
+	/*
+	 * Fill in command table information.  First, the header,
+	 * a SATA Register - Host to Device command FIS.
+	 */
+	ata_tf_to_fis(&qc->tf, pp->cmd_tbl, 0);
+
+	if (!(qc->flags & ATA_QCFLAG_DMAMAP))
+		return;
+
+	ahci_fill_sg(qc);
+}
+
+static inline void ahci_dma_complete (struct ata_port *ap,
+                                     struct ata_queued_cmd *qc,
+				     int have_err)
+{
+	/* get drive status; clear intr; complete txn */
+	ata_qc_complete(ata_qc_from_tag(ap, ap->active_tag),
+			have_err ? ATA_ERR : 0);
+}
+
+static void ahci_intr_error(struct ata_port *ap, u32 irq_stat)
+{
+	void *mmio = ap->host_set->mmio_base;
+	void *port_mmio = ahci_port_base(mmio, ap->port_no);
+	u32 tmp;
+	int work;
+
+	/* stop DMA */
+	tmp = readl(port_mmio + PORT_CMD);
+	tmp &= PORT_CMD_START | PORT_CMD_FIS_RX;
+	writel(tmp, port_mmio + PORT_CMD);
+
+	/* wait for engine to stop.  TODO: this could be
+	 * as long as 500 msec
+	 */
+	work = 1000;
+	while (work-- > 0) {
+		tmp = readl(port_mmio + PORT_CMD);
+		if ((tmp & PORT_CMD_LIST_ON) == 0)
+			break;
+		udelay(10);
+	}
+
+	/* clear SATA phy error, if any */
+	tmp = readl(port_mmio + PORT_SCR_ERR);
+	writel(tmp, port_mmio + PORT_SCR_ERR);
+
+	/* if DRQ/BSY is set, device needs to be reset.
+	 * if so, issue COMRESET
+	 */
+	tmp = readl(port_mmio + PORT_TFDATA);
+	if (tmp & (ATA_BUSY | ATA_DRQ)) {
+		writel(0x301, port_mmio + PORT_SCR_CTL);
+		readl(port_mmio + PORT_SCR_CTL); /* flush */
+		udelay(10);
+		writel(0x300, port_mmio + PORT_SCR_CTL);
+		readl(port_mmio + PORT_SCR_CTL); /* flush */
+	}
+
+	/* re-start DMA */
+	tmp = readl(port_mmio + PORT_CMD);
+	tmp |= PORT_CMD_START | PORT_CMD_FIS_RX;
+	writel(tmp, port_mmio + PORT_CMD);
+	readl(port_mmio + PORT_CMD); /* flush */
+
+	printk(KERN_WARNING "ata%u: error occurred, port reset\n", ap->port_no);
+}
+
+static void ahci_eng_timeout(struct ata_port *ap)
+{
+	void *mmio = ap->host_set->mmio_base;
+	void *port_mmio = ahci_port_base(mmio, ap->port_no);
+	struct ata_queued_cmd *qc;
+
+	DPRINTK("ENTER\n");
+
+	ahci_intr_error(ap, readl(port_mmio + PORT_IRQ_STAT));
+
+	qc = ata_qc_from_tag(ap, ap->active_tag);
+	if (!qc) {
+		printk(KERN_ERR "ata%u: BUG: timeout without command\n",
+		       ap->id);
+	} else {
+		/* hack alert!  We cannot use the supplied completion
+	 	 * function from inside the ->eh_strategy_handler() thread.
+	 	 * libata is the only user of ->eh_strategy_handler() in
+	 	 * any kernel, so the default scsi_done() assumes it is
+	 	 * not being called from the SCSI EH.
+	 	 */
+		qc->scsidone = scsi_finish_command;
+		ata_qc_complete(qc, ATA_ERR);
+	}
+
+}
+
+static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
+{
+	void *mmio = ap->host_set->mmio_base;
+	void *port_mmio = ahci_port_base(mmio, ap->port_no);
+	u32 status, serr, ci;
+
+	serr = readl(port_mmio + PORT_SCR_ERR);
+	writel(serr, port_mmio + PORT_SCR_ERR);
+
+	status = readl(port_mmio + PORT_IRQ_STAT);
+	writel(status, port_mmio + PORT_IRQ_STAT);
+
+	ci = readl(port_mmio + PORT_CMD_ISSUE);
+	if (likely((ci & 0x1) == 0)) {
+		if (qc) {
+			ata_qc_complete(qc, 0);
+			qc = NULL;
+		}
+	}
+
+	if (status & PORT_IRQ_FATAL) {
+		ahci_intr_error(ap, status);
+		if (qc)
+			ata_qc_complete(qc, ATA_ERR);
+	}
+
+	return 1;
+}
+
+static void ahci_irq_clear(struct ata_port *ap)
+{
+	/* TODO */
+}
+
+static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
+{
+	struct ata_host_set *host_set = dev_instance;
+	struct ahci_host_priv *hpriv;
+	unsigned int i, handled = 0;
+	void *mmio;
+	u32 irq_stat, irq_ack = 0;
+
+	VPRINTK("ENTER\n");
+
+	hpriv = host_set->private_data;
+	mmio = host_set->mmio_base;
+
+	/* sigh.  0xffffffff is a valid return from h/w */
+	irq_stat = readl(mmio + HOST_IRQ_STAT);
+	irq_stat &= hpriv->port_map;
+	if (!irq_stat)
+		return IRQ_NONE;
+
+        spin_lock(&host_set->lock);
+
+        for (i = 0; i < host_set->n_ports; i++) {
+		struct ata_port *ap;
+		u32 tmp;
+
+		VPRINTK("port %u\n", i);
+		ap = host_set->ports[i];
+		tmp = irq_stat & (1 << i);
+		if (tmp && ap) {
+			struct ata_queued_cmd *qc;
+			qc = ata_qc_from_tag(ap, ap->active_tag);
+			if (ahci_host_intr(ap, qc))
+				irq_ack |= (1 << i);
+		}
+	}
+
+	if (irq_ack) {
+		writel(irq_ack, mmio + HOST_IRQ_STAT);
+		handled = 1;
+	}
+
+        spin_unlock(&host_set->lock);
+
+	VPRINTK("EXIT\n");
+
+	return IRQ_RETVAL(handled);
+}
+
+static int ahci_qc_issue(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	void *port_mmio = (void *) ap->ioaddr.cmd_addr;
+
+	writel(1, port_mmio + PORT_SCR_ACT);
+	readl(port_mmio + PORT_SCR_ACT);	/* flush */
+
+	writel(1, port_mmio + PORT_CMD_ISSUE);
+	readl(port_mmio + PORT_CMD_ISSUE);	/* flush */
+
+	return 0;
+}
+
+static void ahci_setup_port(struct ata_ioports *port, unsigned long base,
+			    unsigned int port_idx)
+{
+	VPRINTK("ENTER, base==0x%lx, port_idx %u\n", base, port_idx);
+	base = ahci_port_base_ul(base, port_idx);
+	VPRINTK("base now==0x%lx\n", base);
+
+	port->cmd_addr		= base;
+	port->scr_addr		= base + PORT_SCR;
+
+	VPRINTK("EXIT\n");
+}
+
+static int ahci_host_init(struct ata_probe_ent *probe_ent)
+{
+	struct ahci_host_priv *hpriv = probe_ent->private_data;
+	struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
+	void __iomem *mmio = probe_ent->mmio_base;
+	u32 tmp, cap_save;
+	u16 tmp16;
+	unsigned int i, j, using_dac;
+	int rc;
+	void __iomem *port_mmio;
+
+	cap_save = readl(mmio + HOST_CAP);
+	cap_save &= ( (1<<28) | (1<<17) );
+	cap_save |= (1 << 27);
+
+	/* global controller reset */
+	tmp = readl(mmio + HOST_CTL);
+	if ((tmp & HOST_RESET) == 0) {
+		writel(tmp | HOST_RESET, mmio + HOST_CTL);
+		readl(mmio + HOST_CTL); /* flush */
+	}
+
+	/* reset must complete within 1 second, or
+	 * the hardware should be considered fried.
+	 */
+	ssleep(1);
+
+	tmp = readl(mmio + HOST_CTL);
+	if (tmp & HOST_RESET) {
+		printk(KERN_ERR DRV_NAME "(%s): controller reset failed (0x%x)\n",
+			pci_name(pdev), tmp);
+		return -EIO;
+	}
+
+	writel(HOST_AHCI_EN, mmio + HOST_CTL);
+	(void) readl(mmio + HOST_CTL);	/* flush */
+	writel(cap_save, mmio + HOST_CAP);
+	writel(0xf, mmio + HOST_PORTS_IMPL);
+	(void) readl(mmio + HOST_PORTS_IMPL);	/* flush */
+
+	pci_read_config_word(pdev, 0x92, &tmp16);
+	tmp16 |= 0xf;
+	pci_write_config_word(pdev, 0x92, tmp16);
+
+	hpriv->cap = readl(mmio + HOST_CAP);
+	hpriv->port_map = readl(mmio + HOST_PORTS_IMPL);
+	probe_ent->n_ports = (hpriv->cap & 0x1f) + 1;
+
+	VPRINTK("cap 0x%x  port_map 0x%x  n_ports %d\n",
+		hpriv->cap, hpriv->port_map, probe_ent->n_ports);
+
+	using_dac = hpriv->cap & HOST_CAP_64;
+	if (using_dac &&
+	    !pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) {
+		hpriv->flags |= HOST_CAP_64;
+	} else {
+		rc = pci_set_dma_mask(pdev, 0xffffffffULL);
+		if (rc) {
+			printk(KERN_ERR DRV_NAME "(%s): 32-bit DMA enable failed\n",
+				pci_name(pdev));
+			return rc;
+		}
+	}
+
+	for (i = 0; i < probe_ent->n_ports; i++) {
+#if 0 /* BIOSen initialize this incorrectly */
+		if (!(hpriv->port_map & (1 << i)))
+			continue;
+#endif
+
+		port_mmio = ahci_port_base(mmio, i);
+		VPRINTK("mmio %p  port_mmio %p\n", mmio, port_mmio);
+
+		ahci_setup_port(&probe_ent->port[i],
+				(unsigned long) mmio, i);
+
+		/* make sure port is not active */
+		tmp = readl(port_mmio + PORT_CMD);
+		VPRINTK("PORT_CMD 0x%x\n", tmp);
+		if (tmp & (PORT_CMD_LIST_ON | PORT_CMD_FIS_ON |
+			   PORT_CMD_FIS_RX | PORT_CMD_START)) {
+			tmp &= ~(PORT_CMD_LIST_ON | PORT_CMD_FIS_ON |
+				 PORT_CMD_FIS_RX | PORT_CMD_START);
+			writel(tmp, port_mmio + PORT_CMD);
+			readl(port_mmio + PORT_CMD); /* flush */
+
+			/* spec says 500 msecs for each bit, so
+			 * this is slightly incorrect.
+			 */
+			msleep(500);
+		}
+
+		writel(PORT_CMD_SPIN_UP, port_mmio + PORT_CMD);
+
+		j = 0;
+		while (j < 100) {
+			msleep(10);
+			tmp = readl(port_mmio + PORT_SCR_STAT);
+			if ((tmp & 0xf) == 0x3)
+				break;
+			j++;
+		}
+
+		tmp = readl(port_mmio + PORT_SCR_ERR);
+		VPRINTK("PORT_SCR_ERR 0x%x\n", tmp);
+		writel(tmp, port_mmio + PORT_SCR_ERR);
+
+		/* ack any pending irq events for this port */
+		tmp = readl(port_mmio + PORT_IRQ_STAT);
+		VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp);
+		if (tmp)
+			writel(tmp, port_mmio + PORT_IRQ_STAT);
+
+		writel(1 << i, mmio + HOST_IRQ_STAT);
+
+		/* set irq mask (enables interrupts) */
+		writel(DEF_PORT_IRQ, port_mmio + PORT_IRQ_MASK);
+	}
+
+	tmp = readl(mmio + HOST_CTL);
+	VPRINTK("HOST_CTL 0x%x\n", tmp);
+	writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL);
+	tmp = readl(mmio + HOST_CTL);
+	VPRINTK("HOST_CTL 0x%x\n", tmp);
+
+	pci_set_master(pdev);
+
+	return 0;
+}
+
+/* move to PCI layer, integrate w/ MSI stuff */
+static void pci_enable_intx(struct pci_dev *pdev)
+{
+	u16 pci_command;
+
+	pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
+	if (pci_command & PCI_COMMAND_INTX_DISABLE) {
+		pci_command &= ~PCI_COMMAND_INTX_DISABLE;
+		pci_write_config_word(pdev, PCI_COMMAND, pci_command);
+	}
+}
+
+static void ahci_print_info(struct ata_probe_ent *probe_ent)
+{
+	struct ahci_host_priv *hpriv = probe_ent->private_data;
+	struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
+	void *mmio = probe_ent->mmio_base;
+	u32 vers, cap, impl, speed;
+	const char *speed_s;
+	u16 cc;
+	const char *scc_s;
+
+	vers = readl(mmio + HOST_VERSION);
+	cap = hpriv->cap;
+	impl = hpriv->port_map;
+
+	speed = (cap >> 20) & 0xf;
+	if (speed == 1)
+		speed_s = "1.5";
+	else if (speed == 2)
+		speed_s = "3";
+	else
+		speed_s = "?";
+
+	pci_read_config_word(pdev, 0x0a, &cc);
+	if (cc == 0x0101)
+		scc_s = "IDE";
+	else if (cc == 0x0106)
+		scc_s = "SATA";
+	else if (cc == 0x0104)
+		scc_s = "RAID";
+	else
+		scc_s = "unknown";
+
+	printk(KERN_INFO DRV_NAME "(%s) AHCI %02x%02x.%02x%02x "
+		"%u slots %u ports %s Gbps 0x%x impl %s mode\n"
+	       	,
+	       	pci_name(pdev),
+
+	       	(vers >> 24) & 0xff,
+	       	(vers >> 16) & 0xff,
+	       	(vers >> 8) & 0xff,
+	       	vers & 0xff,
+
+		((cap >> 8) & 0x1f) + 1,
+		(cap & 0x1f) + 1,
+		speed_s,
+		impl,
+		scc_s);
+
+	printk(KERN_INFO DRV_NAME "(%s) flags: "
+	       	"%s%s%s%s%s%s"
+	       	"%s%s%s%s%s%s%s\n"
+	       	,
+	       	pci_name(pdev),
+
+		cap & (1 << 31) ? "64bit " : "",
+		cap & (1 << 30) ? "ncq " : "",
+		cap & (1 << 28) ? "ilck " : "",
+		cap & (1 << 27) ? "stag " : "",
+		cap & (1 << 26) ? "pm " : "",
+		cap & (1 << 25) ? "led " : "",
+
+		cap & (1 << 24) ? "clo " : "",
+		cap & (1 << 19) ? "nz " : "",
+		cap & (1 << 18) ? "only " : "",
+		cap & (1 << 17) ? "pmp " : "",
+		cap & (1 << 15) ? "pio " : "",
+		cap & (1 << 14) ? "slum " : "",
+		cap & (1 << 13) ? "part " : ""
+		);
+}
+
+static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	static int printed_version;
+	struct ata_probe_ent *probe_ent = NULL;
+	struct ahci_host_priv *hpriv;
+	unsigned long base;
+	void *mmio_base;
+	unsigned int board_idx = (unsigned int) ent->driver_data;
+	int rc;
+
+	VPRINTK("ENTER\n");
+
+	if (!printed_version++)
+		printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
+
+	rc = pci_enable_device(pdev);
+	if (rc)
+		return rc;
+
+	rc = pci_request_regions(pdev, DRV_NAME);
+	if (rc)
+		goto err_out;
+
+	pci_enable_intx(pdev);
+
+	probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
+	if (probe_ent == NULL) {
+		rc = -ENOMEM;
+		goto err_out_regions;
+	}
+
+	memset(probe_ent, 0, sizeof(*probe_ent));
+	probe_ent->dev = pci_dev_to_dev(pdev);
+	INIT_LIST_HEAD(&probe_ent->node);
+
+	mmio_base = ioremap(pci_resource_start(pdev, AHCI_PCI_BAR),
+		            pci_resource_len(pdev, AHCI_PCI_BAR));
+	if (mmio_base == NULL) {
+		rc = -ENOMEM;
+		goto err_out_free_ent;
+	}
+	base = (unsigned long) mmio_base;
+
+	hpriv = kmalloc(sizeof(*hpriv), GFP_KERNEL);
+	if (!hpriv) {
+		rc = -ENOMEM;
+		goto err_out_iounmap;
+	}
+	memset(hpriv, 0, sizeof(*hpriv));
+
+	probe_ent->sht		= ahci_port_info[board_idx].sht;
+	probe_ent->host_flags	= ahci_port_info[board_idx].host_flags;
+	probe_ent->pio_mask	= ahci_port_info[board_idx].pio_mask;
+	probe_ent->udma_mask	= ahci_port_info[board_idx].udma_mask;
+	probe_ent->port_ops	= ahci_port_info[board_idx].port_ops;
+
+       	probe_ent->irq = pdev->irq;
+       	probe_ent->irq_flags = SA_SHIRQ;
+	probe_ent->mmio_base = mmio_base;
+	probe_ent->private_data = hpriv;
+
+	/* initialize adapter */
+	rc = ahci_host_init(probe_ent);
+	if (rc)
+		goto err_out_hpriv;
+
+	ahci_print_info(probe_ent);
+
+	ata_add_to_probe_list(probe_ent);
+
+	return 0;
+
+err_out_hpriv:
+	kfree(hpriv);
+err_out_iounmap:
+	iounmap(mmio_base);
+err_out_free_ent:
+	kfree(probe_ent);
+err_out_regions:
+	pci_release_regions(pdev);
+err_out:
+	pci_disable_device(pdev);
+	return rc;
+}
+
+
+static int __init ahci_init(void)
+{
+	int rc;
+
+	rc = pci_module_init(&ahci_pci_driver);
+	if (rc)
+		return rc;
+
+	rc = scsi_register_module(MODULE_SCSI_HA, &ahci_sht);
+	if (rc) {
+		rc = -ENODEV;
+		goto err_out;
+	}
+
+	return 0;
+
+err_out:
+	pci_unregister_driver(&ahci_pci_driver);
+	return rc;
+}
+
+
+static void __exit ahci_exit(void)
+{
+	scsi_unregister_module(MODULE_SCSI_HA, &ahci_sht);
+	pci_unregister_driver(&ahci_pci_driver);
+}
+
+
+MODULE_AUTHOR("Jeff Garzik");
+MODULE_DESCRIPTION("AHCI SATA low-level driver");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, ahci_pci_tbl);
+
+module_init(ahci_init);
+module_exit(ahci_exit);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/scsi/ata_piix.c linux-2.4.29-pre3/drivers/scsi/ata_piix.c
--- linux-2.4.28/drivers/scsi/ata_piix.c	2004-12-22 16:17:18.244189152 +0000
+++ linux-2.4.29-pre3/drivers/scsi/ata_piix.c	2004-12-22 16:07:45.405273904 +0000
@@ -32,7 +32,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME	"ata_piix"
-#define DRV_VERSION	"1.02"
+#define DRV_VERSION	"1.03"
 
 enum {
 	PIIX_IOCFG		= 0x54, /* IDE I/O configuration register */
@@ -248,6 +248,7 @@ MODULE_AUTHOR("Andre Hedrick, Alan Cox, 
 MODULE_DESCRIPTION("SCSI low-level driver for Intel PIIX/ICH ATA controllers");
 MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(pci, piix_pci_tbl);
+MODULE_VERSION(DRV_VERSION);
 
 /**
  *	piix_pata_cbl_detect - Probe host controller cable detect info
@@ -261,7 +262,7 @@ MODULE_DEVICE_TABLE(pci, piix_pci_tbl);
  */
 static void piix_pata_cbl_detect(struct ata_port *ap)
 {
-	struct pci_dev *pdev = ap->host_set->pdev;
+	struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
 	u8 tmp, mask;
 
 	/* no 80c support in host controller? */
@@ -294,8 +295,9 @@ cbl40:
 
 static void piix_pata_phy_reset(struct ata_port *ap)
 {
-	if (!pci_test_config_bits(ap->host_set->pdev,
-				  &piix_enable_bits[ap->hard_port_no])) {
+	struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
+
+	if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->hard_port_no])) {
 		ata_port_disable(ap);
 		printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id);
 		return;
@@ -323,7 +325,7 @@ static void piix_pata_phy_reset(struct a
  */
 static int piix_sata_probe (struct ata_port *ap)
 {
-	struct pci_dev *pdev = ap->host_set->pdev;
+	struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
 	int combined = (ap->flags & ATA_FLAG_SLAVE_POSS);
 	int orig_mask, mask, i;
 	u8 pcs;
@@ -393,7 +395,7 @@ static void piix_sata_phy_reset(struct a
 static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev)
 {
 	unsigned int pio	= adev->pio_mode - XFER_PIO_0;
-	struct pci_dev *dev	= ap->host_set->pdev;
+	struct pci_dev *dev	= to_pci_dev(ap->host_set->dev);
 	unsigned int is_slave	= (adev->devno != 0);
 	unsigned int master_port= ap->hard_port_no ? 0x42 : 0x40;
 	unsigned int slave_port	= 0x44;
@@ -445,7 +447,7 @@ static void piix_set_piomode (struct ata
 static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev)
 {
 	unsigned int udma	= adev->dma_mode; /* FIXME: MWDMA too */
-	struct pci_dev *dev	= ap->host_set->pdev;
+	struct pci_dev *dev	= to_pci_dev(ap->host_set->dev);
 	u8 maslave		= ap->hard_port_no ? 0x42 : 0x40;
 	u8 speed		= udma;
 	unsigned int drive_dn	= (ap->hard_port_no ? 2 : 0) + adev->devno;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/scsi/dpt/dpti_ioctl.h linux-2.4.29-pre3/drivers/scsi/dpt/dpti_ioctl.h
--- linux-2.4.28/drivers/scsi/dpt/dpti_ioctl.h	2001-09-07 16:28:38.000000000 +0000
+++ linux-2.4.29-pre3/drivers/scsi/dpt/dpti_ioctl.h	2004-12-22 16:06:34.886994312 +0000
@@ -3,7 +3,7 @@
                              -------------------
     begin                : Thu Sep 7 2000
     copyright            : (C) 2001 by Adaptec
-    email                : deanna_bonds@adaptec.com
+    email                : aacraid@adaptec.com
 
     See README.dpti for history, notes, license info, and credits
  ***************************************************************************/
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/scsi/dpt_i2o.c linux-2.4.29-pre3/drivers/scsi/dpt_i2o.c
--- linux-2.4.28/drivers/scsi/dpt_i2o.c	2004-12-22 16:17:18.257187176 +0000
+++ linux-2.4.29-pre3/drivers/scsi/dpt_i2o.c	2004-12-22 16:07:29.797646624 +0000
@@ -3,7 +3,7 @@
                              -------------------
     begin                : Thu Sep 7 2000
     copyright            : (C) 2000 by Adaptec
-    email                : deanna_bonds@adaptec.com
+    email                : aacraid@adaptec.com
 
     			   July 30, 2001 First version being submitted
 			   for inclusion in the kernel.  V2.4
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/scsi/dpti.h linux-2.4.29-pre3/drivers/scsi/dpti.h
--- linux-2.4.28/drivers/scsi/dpti.h	2001-09-07 16:28:38.000000000 +0000
+++ linux-2.4.29-pre3/drivers/scsi/dpti.h	2004-12-22 16:05:31.216673672 +0000
@@ -3,7 +3,7 @@
                              -------------------
     begin                : Thu Sep 7 2000
     copyright            : (C) 2001 by Adaptec
-    email                : deanna_bonds@adaptec.com
+    email                : aacraid@adaptec.com
 
     See README.dpti for history, notes, license info, and credits
  ***************************************************************************/
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/scsi/ide-scsi.c linux-2.4.29-pre3/drivers/scsi/ide-scsi.c
--- linux-2.4.28/drivers/scsi/ide-scsi.c	2003-11-28 18:26:20.000000000 +0000
+++ linux-2.4.29-pre3/drivers/scsi/ide-scsi.c	2004-12-22 16:05:32.256515592 +0000
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/scsi/ide-scsi.c	Version 0.93    June 10, 2002
+ * linux/drivers/scsi/ide-scsi.c	Version 0.94    Sept 09, 2003
  *
  * Copyright (C) 1996 - 1999 Gadi Oxman <gadio@netvision.net.il>
  * Copyright (C) 2001 - 2002 Andre Hedrick <andre@linux-ide.org>
@@ -35,9 +35,12 @@
  * Ver 0.92  Mar 21 02   Include DevFs support
  *                        Borsenkow Andrej <Andrej.Borsenkow@mow.siemens.ru>
  * Ver 0.93  Jun 10 02   Fix "off by one" error in transforms
+ * Ver 0.94  Sep 09 03   Added transform for reading ATAPI tape drive block
+ *                        limits (ATAPI tapes report block limits in mode
+ *                        page 0x2A, not by "read block limits" command)
  */
 
-#define IDESCSI_VERSION "0.93"
+#define IDESCSI_VERSION "0.94"
 
 #include <linux/module.h>
 #include <linux/config.h>
@@ -234,6 +237,25 @@ static inline void idescsi_transform_pc1
 			pc->buffer_size += 4;
 		}
 	}
+	if (drive->media == ide_tape) {
+		if (sc[0] == READ_BLOCK_LIMITS) {	/* IDE tapes have blk lmts in mode page 0x2a */
+			if (!scsi_buf)
+				return;
+			/* buffer size should be 6 for READ_BLOCK_LIMITS    */
+			/* we need 12 bytes (4 for header + 8 for mode page */
+			if ((atapi_buf = kmalloc(12, GFP_ATOMIC)) == NULL)
+				return;
+			memset(atapi_buf, 0, 12);
+			memset (c, 0, 12);
+			c[0] = MODE_SENSE;
+			c[1] = 8;  	/* no block descriptors     */
+			c[2] = 0x2A;	/* mode page 0x2A           */
+			c[4] = 12;	/* buffer length 12 decimal */
+			pc->buffer = atapi_buf;
+			pc->request_transfer = 12;
+			pc->buffer_size = 12;
+		}
+	}
 }
 
 static inline void idescsi_transform_pc2 (ide_drive_t *drive, idescsi_pc_t *pc)
@@ -262,7 +284,19 @@ static inline void idescsi_transform_pc2
 			/* response data format */
 			scsi_buf[3] = (scsi_buf[3] & 0xf0) | 2;
 		}
+	}	
+	if (drive->media == ide_tape) {
+		if (sc[0] == READ_BLOCK_LIMITS) {
+			memset(scsi_buf, 0, pc->scsi_cmd->request_bufflen);
+			/* granularity of 9 (always 9 for ide tapes) */
+			scsi_buf[0] = 9;
+			/* block length of 1024 bytes supported? */
+			scsi_buf[2] = (atapi_buf[11] & 0x04) ? 4 : 2;
+			/* block length of 512 bytes supported?  */
+			scsi_buf[4] = (atapi_buf[11] & 0x02) ? 2 : 4;
+		}
 	}
+
 	if (atapi_buf && atapi_buf != scsi_buf)
 		kfree(atapi_buf);
 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/scsi/libata-core.c linux-2.4.29-pre3/drivers/scsi/libata-core.c
--- linux-2.4.28/drivers/scsi/libata-core.c	2004-12-22 16:17:18.425161640 +0000
+++ linux-2.4.29-pre3/drivers/scsi/libata-core.c	2004-12-22 16:06:57.343580392 +0000
@@ -57,6 +57,7 @@ static int ata_choose_xfer_mode(struct a
 				u8 *xfer_mode_out,
 				unsigned int *xfer_shift_out);
 static int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat);
+static void __ata_qc_complete(struct ata_queued_cmd *qc);
 
 static unsigned int ata_unique_id = 1;
 static LIST_HEAD(ata_probe_list);
@@ -65,28 +66,7 @@ static spinlock_t ata_module_lock = SPIN
 MODULE_AUTHOR("Jeff Garzik");
 MODULE_DESCRIPTION("Library module for ATA devices");
 MODULE_LICENSE("GPL");
-
-/**
- *	msleep - sleep for a number of milliseconds
- *	@msecs: number of milliseconds to sleep
- *
- *	Issues schedule_timeout call for the specified number
- *	of milliseconds.
- *
- *	LOCKING:
- *	None.
- */
-
-static void msleep(unsigned long msecs)
-{
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(msecs_to_jiffies(msecs) + 1);
-}
-
-void libata_msleep(unsigned long msecs)
-{
-	msleep(msecs);
-}
+MODULE_VERSION(DRV_VERSION);
 
 /**
  *	ata_tf_load - send taskfile registers to host controller
@@ -601,7 +581,7 @@ static const char * xfer_mode_str[] = {
 
 /**
  *	ata_udma_string - convert UDMA bit offset to string
- *	@udma_mask: mask of bits supported; only highest bit counts.
+ *	@mask: mask of bits supported; only highest bit counts.
  *
  *	Determine string which represents the highest speed
  *	(highest bit in @udma_mask).
@@ -838,7 +818,7 @@ static u8 ata_dev_try_classify(struct at
 
 /**
  *	ata_dev_id_string - Convert IDENTIFY DEVICE page into string
- *	@dev: Device whose IDENTIFY DEVICE results we will examine
+ *	@id: IDENTIFY DEVICE results we will examine
  *	@s: string into which data is output
  *	@ofs: offset into identify device page
  *	@len: length of string to return. must be an even number.
@@ -851,17 +831,17 @@ static u8 ata_dev_try_classify(struct at
  *	caller.
  */
 
-void ata_dev_id_string(struct ata_device *dev, unsigned char *s,
+void ata_dev_id_string(u16 *id, unsigned char *s,
 		       unsigned int ofs, unsigned int len)
 {
 	unsigned int c;
 
 	while (len > 0) {
-		c = dev->id[ofs] >> 8;
+		c = id[ofs] >> 8;
 		*s = c;
 		s++;
 
-		c = dev->id[ofs] & 0xff;
+		c = id[ofs] & 0xff;
 		*s = c;
 		s++;
 
@@ -1037,7 +1017,7 @@ static void ata_dev_identify(struct ata_
 	BUG_ON(qc == NULL);
 
 	ata_sg_init_one(qc, dev->id, sizeof(dev->id));
-	qc->pci_dma_dir = PCI_DMA_FROMDEVICE;
+	qc->dma_dir = DMA_FROM_DEVICE;
 	qc->tf.protocol = ATA_PROT_PIO;
 	qc->nsect = 1;
 
@@ -1104,7 +1084,7 @@ retry:
 	 */
 
 	/* we require LBA and DMA support (bits 8 & 9 of word 49) */
-	if (!ata_id_has_dma(dev) || !ata_id_has_lba(dev)) {
+	if (!ata_id_has_dma(dev->id) || !ata_id_has_lba(dev->id)) {
 		printk(KERN_DEBUG "ata%u: no dma/lba\n", ap->id);
 		goto err_out_nosup;
 	}
@@ -1122,7 +1102,7 @@ retry:
 
 	/* ATA-specific feature tests */
 	if (dev->class == ATA_DEV_ATA) {
-		if (!ata_id_is_ata(dev))	/* sanity check */
+		if (!ata_id_is_ata(dev->id))	/* sanity check */
 			goto err_out_nosup;
 
 		tmp = dev->id[ATA_ID_MAJOR_VER];
@@ -1136,11 +1116,11 @@ retry:
 			goto err_out_nosup;
 		}
 
-		if (ata_id_has_lba48(dev)) {
+		if (ata_id_has_lba48(dev->id)) {
 			dev->flags |= ATA_DFLAG_LBA48;
-			dev->n_sectors = ata_id_u64(dev, 100);
+			dev->n_sectors = ata_id_u64(dev->id, 100);
 		} else {
-			dev->n_sectors = ata_id_u32(dev, 60);
+			dev->n_sectors = ata_id_u32(dev->id, 60);
 		}
 
 		ap->host->max_cmd_len = 16;
@@ -1155,7 +1135,7 @@ retry:
 
 	/* ATAPI-specific feature tests */
 	else {
-		if (ata_id_is_ata(dev))		/* sanity check */
+		if (ata_id_is_ata(dev->id))		/* sanity check */
 			goto err_out_nosup;
 
 		rc = atapi_cdb_len(dev->id);
@@ -1785,8 +1765,10 @@ static int fgb(u32 bitmap)
 }
 
 /**
- *	ata_choose_xfer_mode -
- *	@ap:
+ *	ata_choose_xfer_mode - attempt to find best transfer mode
+ *	@ap: Port for which an xfer mode will be selected
+ *	@xfer_mode_out: (output) SET FEATURES - XFER MODE code
+ *	@xfer_shift_out: (output) bit shift that selects this mode
  *
  *	LOCKING:
  *
@@ -1869,7 +1851,7 @@ static void ata_sg_clean(struct ata_queu
 {
 	struct ata_port *ap = qc->ap;
 	struct scatterlist *sg = qc->sg;
-	int dir = qc->pci_dma_dir;
+	int dir = qc->dma_dir;
 
 	assert(qc->flags & ATA_QCFLAG_DMAMAP);
 	assert(sg != NULL);
@@ -1880,9 +1862,9 @@ static void ata_sg_clean(struct ata_queu
 	DPRINTK("unmapping %u sg elements\n", qc->n_elem);
 
 	if (qc->flags & ATA_QCFLAG_SG)
-		pci_unmap_sg(ap->host_set->pdev, sg, qc->n_elem, dir);
+		dma_unmap_sg(ap->host_set->dev, sg, qc->n_elem, dir);
 	else
-		pci_unmap_single(ap->host_set->pdev, sg_dma_address(&sg[0]),
+		dma_unmap_single(ap->host_set->dev, sg_dma_address(&sg[0]),
 				 sg_dma_len(&sg[0]), dir);
 
 	qc->flags &= ~ATA_QCFLAG_DMAMAP;
@@ -1967,8 +1949,6 @@ void ata_sg_init_one(struct ata_queued_c
 	sg->page = virt_to_page(buf);
 	sg->offset = (unsigned long) buf & ~PAGE_MASK;
 	sg_dma_len(sg) = buflen;
-
-	WARN_ON(buflen > PAGE_SIZE);
 }
 
 void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
@@ -1993,12 +1973,14 @@ void ata_sg_init(struct ata_queued_cmd *
 static int ata_sg_setup_one(struct ata_queued_cmd *qc)
 {
 	struct ata_port *ap = qc->ap;
-	int dir = qc->pci_dma_dir;
+	int dir = qc->dma_dir;
 	struct scatterlist *sg = qc->sg;
 	dma_addr_t dma_address;
 
-	dma_address = pci_map_single(ap->host_set->pdev, qc->buf_virt,
+	dma_address = dma_map_single(ap->host_set->dev, qc->buf_virt,
 				     sg_dma_len(sg), dir);
+	if (dma_mapping_error(dma_address))
+		return -1;
 
 	sg_dma_address(sg) = dma_address;
 
@@ -2028,8 +2010,8 @@ static int ata_sg_setup(struct ata_queue
 	VPRINTK("ENTER, ata%u\n", ap->id);
 	assert(qc->flags & ATA_QCFLAG_SG);
 
-	dir = qc->pci_dma_dir;
-	n_elem = pci_map_sg(ap->host_set->pdev, sg, qc->n_elem, dir);
+	dir = qc->dma_dir;
+	n_elem = dma_map_sg(ap->host_set->dev, sg, qc->n_elem, dir);
 	if (n_elem < 1)
 		return -1;
 
@@ -2187,14 +2169,20 @@ static void ata_pio_sector(struct ata_qu
 	struct scatterlist *sg = qc->sg;
 	struct ata_port *ap = qc->ap;
 	struct page *page;
+	unsigned int offset;
 	unsigned char *buf;
 
 	if (qc->cursect == (qc->nsect - 1))
 		ap->pio_task_state = PIO_ST_LAST;
 
 	page = sg[qc->cursg].page;
-	buf = kmap(page) +
-	      sg[qc->cursg].offset + (qc->cursg_ofs * ATA_SECT_SIZE);
+	offset = sg[qc->cursg].offset + qc->cursg_ofs * ATA_SECT_SIZE;
+
+	/* get the current page and offset */
+	page = nth_page(page, (offset >> PAGE_SHIFT));
+	offset %= PAGE_SIZE;
+
+	buf = kmap(page) + offset;
 
 	qc->cursect++;
 	qc->cursg_ofs++;
@@ -2213,11 +2201,64 @@ static void ata_pio_sector(struct ata_qu
 	kunmap(page);
 }
 
-static void atapi_pio_sector(struct ata_queued_cmd *qc)
+static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
+{
+	int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
+	struct scatterlist *sg = qc->sg;
+	struct ata_port *ap = qc->ap;
+	struct page *page;
+	unsigned char *buf;
+	unsigned int offset, count;
+
+	if (qc->curbytes == qc->nbytes - bytes)
+		ap->pio_task_state = PIO_ST_LAST;
+
+next_sg:
+	sg = &qc->sg[qc->cursg];
+
+next_page:
+	page = sg->page;
+	offset = sg->offset + qc->cursg_ofs;
+
+	/* get the current page and offset */
+	page = nth_page(page, (offset >> PAGE_SHIFT));
+	offset %= PAGE_SIZE;
+
+	count = min(sg_dma_len(sg) - qc->cursg_ofs, bytes);
+
+	/* don't cross page boundaries */
+	count = min(count, (unsigned int)PAGE_SIZE - offset);
+
+	buf = kmap(page) + offset;
+
+	bytes -= count;
+	qc->curbytes += count;
+	qc->cursg_ofs += count;
+
+	if (qc->cursg_ofs == sg_dma_len(sg)) {
+		qc->cursg++;
+		qc->cursg_ofs = 0;
+	}
+
+	DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
+
+	/* do the actual data transfer */
+	ata_data_xfer(ap, buf, count, do_write);
+
+	kunmap(page);
+
+	if (bytes) {
+		if (qc->cursg_ofs < sg_dma_len(sg))
+			goto next_page;
+		goto next_sg;
+	}
+}
+
+static void atapi_pio_bytes(struct ata_queued_cmd *qc)
 {
 	struct ata_port *ap = qc->ap;
 	struct ata_device *dev = qc->dev;
-	unsigned int i, ireason, bc_lo, bc_hi, bytes;
+	unsigned int ireason, bc_lo, bc_hi, bytes;
 	int i_write, do_write = (qc->tf.flags & ATA_TFLAG_WRITE) ? 1 : 0;
 
 	ap->ops->tf_read(ap, &qc->tf);
@@ -2235,16 +2276,7 @@ static void atapi_pio_sector(struct ata_
 	if (do_write != i_write)
 		goto err_out;
 
-	/* make sure byte count is multiple of sector size; not
-	* required by standard (warning! warning!), but IDE driver
-	* does this to simplify things a bit.  We are lazy, and
-	* follow suit.
-	*/
-	if (bytes & (ATA_SECT_SIZE - 1))
-		goto err_out;
-
-	for (i = 0; i < (bytes >> 9); i++)
-		ata_pio_sector(qc);
+	__atapi_pio_bytes(qc, bytes);
 
 	return;
 
@@ -2285,19 +2317,30 @@ static void ata_pio_block(struct ata_por
 		}
 	}
 
-	/* handle BSY=0, DRQ=0 as error */
-	if ((status & ATA_DRQ) == 0) {
-		ap->pio_task_state = PIO_ST_ERR;
-		return;
-	}
-
 	qc = ata_qc_from_tag(ap, ap->active_tag);
 	assert(qc != NULL);
 
-	if (is_atapi_taskfile(&qc->tf))
-		atapi_pio_sector(qc);
-	else
+	if (is_atapi_taskfile(&qc->tf)) {
+		/* no more data to transfer or unsupported ATAPI command */
+		if ((status & ATA_DRQ) == 0) {
+			ap->pio_task_state = PIO_ST_IDLE;
+
+			ata_irq_on(ap);
+
+			ata_qc_complete(qc, status);
+			return;
+		}
+
+		atapi_pio_bytes(qc);
+	} else {
+		/* handle BSY=0, DRQ=0 as error */
+		if ((status & ATA_DRQ) == 0) {
+			ap->pio_task_state = PIO_ST_ERR;
+			return;
+		}
+
 		ata_pio_sector(qc);
+	}
 }
 
 static void ata_pio_error(struct ata_port *ap)
@@ -2356,6 +2399,59 @@ static void ata_pio_task(void *_data)
 	}
 }
 
+static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
+				struct scsi_cmnd *cmd)
+{
+	DECLARE_COMPLETION(wait);
+	struct ata_queued_cmd *qc;
+	unsigned long flags;
+	int using_pio = dev->flags & ATA_DFLAG_PIO;
+	int rc;
+
+	DPRINTK("ATAPI request sense\n");
+
+	qc = ata_qc_new_init(ap, dev);
+	BUG_ON(qc == NULL);
+
+	/* FIXME: is this needed? */
+	memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
+
+	ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer));
+	qc->dma_dir = DMA_FROM_DEVICE;
+
+	memset(&qc->cdb, 0, sizeof(ap->cdb_len));
+	qc->cdb[0] = REQUEST_SENSE;
+	qc->cdb[4] = SCSI_SENSE_BUFFERSIZE;
+
+	qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+	qc->tf.command = ATA_CMD_PACKET;
+
+	if (using_pio) {
+		qc->tf.protocol = ATA_PROT_ATAPI;
+		qc->tf.lbam = (8 * 1024) & 0xff;
+		qc->tf.lbah = (8 * 1024) >> 8;
+
+		qc->nbytes = SCSI_SENSE_BUFFERSIZE;
+	} else {
+		qc->tf.protocol = ATA_PROT_ATAPI_DMA;
+		qc->tf.feature |= ATAPI_PKT_DMA;
+	}
+
+	qc->waiting = &wait;
+	qc->complete_fn = ata_qc_complete_noop;
+
+	spin_lock_irqsave(&ap->host_set->lock, flags);
+	rc = ata_qc_issue(qc);
+	spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+	if (rc)
+		ata_port_disable(ap);
+	else
+		wait_for_completion(&wait);
+
+	DPRINTK("EXIT\n");
+}
+
 /**
  *	ata_qc_timeout - Handle timeout of queued command
  *	@qc: Command that timed out
@@ -2377,10 +2473,29 @@ static void ata_pio_task(void *_data)
 static void ata_qc_timeout(struct ata_queued_cmd *qc)
 {
 	struct ata_port *ap = qc->ap;
+	struct ata_device *dev = qc->dev;
 	u8 host_stat = 0, drv_stat;
 
 	DPRINTK("ENTER\n");
 
+	/* FIXME: doesn't this conflict with timeout handling? */
+	if (qc->dev->class == ATA_DEV_ATAPI && qc->scsicmd) {
+		struct scsi_cmnd *cmd = qc->scsicmd;
+
+		if (cmd->owner == SCSI_OWNER_ERROR_HANDLER) {
+
+			/* finish completing original command */
+			__ata_qc_complete(qc);
+
+			atapi_request_sense(ap, dev, cmd);
+
+			cmd->result = (CHECK_CONDITION << 1) | (DID_OK << 16);
+			scsi_finish_command(cmd);
+
+			goto out;
+		}
+	}
+
 	/* hack alert!  We cannot use the supplied completion
 	 * function from inside the ->eh_strategy_handler() thread.
 	 * libata is the only user of ->eh_strategy_handler() in
@@ -2414,7 +2529,7 @@ static void ata_qc_timeout(struct ata_qu
 		ata_qc_complete(qc, drv_stat);
 		break;
 	}
-
+out:
 	DPRINTK("EXIT\n");
 }
 
@@ -2503,6 +2618,7 @@ struct ata_queued_cmd *ata_qc_new_init(s
 		qc->dev = dev;
 		qc->cursect = qc->cursg = qc->cursg_ofs = 0;
 		qc->nsect = 0;
+		qc->nbytes = qc->curbytes = 0;
 
 		ata_tf_init(ap, &qc->tf, dev->devno);
 
@@ -2518,6 +2634,30 @@ static int ata_qc_complete_noop(struct a
 	return 0;
 }
 
+static void __ata_qc_complete(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	unsigned int tag, do_clear = 0;
+
+	qc->flags = 0;
+	tag = qc->tag;
+	if (likely(ata_tag_valid(tag))) {
+		if (tag == ap->active_tag)
+			ap->active_tag = ATA_TAG_POISON;
+		qc->tag = ATA_TAG_POISON;
+		do_clear = 1;
+	}
+
+	if (qc->waiting) {
+		struct completion *waiting = qc->waiting;
+		qc->waiting = NULL;
+		complete(waiting);
+	}
+
+	if (likely(do_clear))
+		clear_bit(tag, &ap->qactive);
+}
+
 /**
  *	ata_qc_complete - Complete an active ATA command
  *	@qc: Command to complete
@@ -2529,8 +2669,6 @@ static int ata_qc_complete_noop(struct a
 
 void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat)
 {
-	struct ata_port *ap = qc->ap;
-	unsigned int tag, do_clear = 0;
 	int rc;
 
 	assert(qc != NULL);	/* ata_qc_from_tag _might_ return NULL */
@@ -2548,25 +2686,33 @@ void ata_qc_complete(struct ata_queued_c
 	if (rc != 0)
 		return;
 
-	qc->flags = 0;
-	tag = qc->tag;
-	if (likely(ata_tag_valid(tag))) {
-		if (tag == ap->active_tag)
-			ap->active_tag = ATA_TAG_POISON;
-		qc->tag = ATA_TAG_POISON;
-		do_clear = 1;
-	}
+	__ata_qc_complete(qc);
 
-	if (qc->waiting) {
-		struct completion *waiting = qc->waiting;
-		qc->waiting = NULL;
-		complete(waiting);
-	}
+	VPRINTK("EXIT\n");
+}
 
-	if (likely(do_clear))
-		clear_bit(tag, &ap->qactive);
+static inline int ata_should_dma_map(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
 
-	VPRINTK("EXIT\n");
+	switch (qc->tf.protocol) {
+	case ATA_PROT_DMA:
+	case ATA_PROT_ATAPI_DMA:
+		return 1;
+
+	case ATA_PROT_ATAPI:
+	case ATA_PROT_PIO:
+	case ATA_PROT_PIO_MULT:
+		if (ap->flags & ATA_FLAG_PIO_DMA)
+			return 1;
+
+		/* fall through */
+	
+	default:
+		return 0;
+	}
+
+	/* never reached */
 }
 
 /**
@@ -2589,12 +2735,16 @@ int ata_qc_issue(struct ata_queued_cmd *
 {
 	struct ata_port *ap = qc->ap;
 
-	if (qc->flags & ATA_QCFLAG_SG) {
-		if (ata_sg_setup(qc))
-			goto err_out;
-	} else if (qc->flags & ATA_QCFLAG_SINGLE) {
-		if (ata_sg_setup_one(qc))
-			goto err_out;
+	if (ata_should_dma_map(qc)) {
+		if (qc->flags & ATA_QCFLAG_SG) {
+			if (ata_sg_setup(qc))
+				goto err_out;
+		} else if (qc->flags & ATA_QCFLAG_SINGLE) {
+			if (ata_sg_setup_one(qc))
+				goto err_out;
+		}
+	} else {
+		qc->flags &= ~ATA_QCFLAG_DMAMAP;
 	}
 
 	ap->ops->qc_prep(qc);
@@ -2983,9 +3133,9 @@ err_out:
 
 int ata_port_start (struct ata_port *ap)
 {
-	struct pci_dev *pdev = ap->host_set->pdev;
+	struct device *dev = ap->host_set->dev;
 
-	ap->prd = pci_alloc_consistent(pdev, ATA_PRD_TBL_SZ, &ap->prd_dma);
+	ap->prd = dma_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma, GFP_KERNEL);
 	if (!ap->prd)
 		return -ENOMEM;
 
@@ -2996,9 +3146,9 @@ int ata_port_start (struct ata_port *ap)
 
 void ata_port_stop (struct ata_port *ap)
 {
-	struct pci_dev *pdev = ap->host_set->pdev;
+	struct device *dev = ap->host_set->dev;
 
-	pci_free_consistent(pdev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma);
+	dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma);
 }
 
 /**
@@ -3044,7 +3194,7 @@ static void ata_host_init(struct ata_por
 	host->max_channel = 1;
 	host->unique_id = ata_unique_id++;
 	host->max_cmd_len = 12;
-	host->pci_dev = ent->pdev;
+	host->pci_dev = to_pci_dev(ent->dev);
 
 	ap->flags = ATA_FLAG_PORT_DISABLED;
 	ap->id = host->unique_id;
@@ -3130,7 +3280,7 @@ err_out:
 int ata_device_add(struct ata_probe_ent *ent)
 {
 	unsigned int count = 0, i;
-	struct pci_dev *pdev = ent->pdev;
+	struct device *dev = ent->dev;
 	struct ata_host_set *host_set;
 
 	DPRINTK("ENTER\n");
@@ -3142,7 +3292,7 @@ int ata_device_add(struct ata_probe_ent 
 	memset(host_set, 0, sizeof(struct ata_host_set) + (ent->n_ports * sizeof(void *)));
 	spin_lock_init(&host_set->lock);
 
-	host_set->pdev = pdev;
+	host_set->dev = dev;
 	host_set->n_ports = ent->n_ports;
 	host_set->irq = ent->irq;
 	host_set->mmio_base = ent->mmio_base;
@@ -3211,7 +3361,7 @@ int ata_device_add(struct ata_probe_ent 
 		}
 	}
 
-	pci_set_drvdata(pdev, host_set);
+	dev_set_drvdata(dev, host_set);
 
 	VPRINTK("EXIT, returning %u\n", ent->n_ports);
 	return ent->n_ports; /* success */
@@ -3310,7 +3460,7 @@ void ata_std_ports(struct ata_ioports *i
 }
 
 static struct ata_probe_ent *
-ata_probe_ent_alloc(int n, struct pci_dev *pdev, struct ata_port_info **port)
+ata_probe_ent_alloc(int n, struct device *dev, struct ata_port_info **port)
 {
 	struct ata_probe_ent *probe_ent;
 	int i;
@@ -3318,7 +3468,7 @@ ata_probe_ent_alloc(int n, struct pci_de
 	probe_ent = kmalloc(sizeof(*probe_ent) * n, GFP_KERNEL);
 	if (!probe_ent) {
 		printk(KERN_ERR DRV_NAME "(%s): out of memory\n",
-		       pci_name(pdev));
+		       pci_name(to_pci_dev(dev)));
 		return NULL;
 	}
 
@@ -3326,7 +3476,7 @@ ata_probe_ent_alloc(int n, struct pci_de
 
 	for (i = 0; i < n; i++) {
 		INIT_LIST_HEAD(&probe_ent[i].node);
-		probe_ent[i].pdev = pdev;
+		probe_ent[i].dev = dev;
 
 		probe_ent[i].sht = port[i]->sht;
 		probe_ent[i].host_flags = port[i]->host_flags;
@@ -3340,10 +3490,12 @@ ata_probe_ent_alloc(int n, struct pci_de
 	return probe_ent;
 }
 
+#ifdef CONFIG_PCI
 struct ata_probe_ent *
 ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port)
 {
-	struct ata_probe_ent *probe_ent = ata_probe_ent_alloc(1, pdev, port);
+	struct ata_probe_ent *probe_ent =
+		ata_probe_ent_alloc(1, pci_dev_to_dev(pdev), port);
 	if (!probe_ent)
 		return NULL;
 
@@ -3372,7 +3524,8 @@ ata_pci_init_native_mode(struct pci_dev 
 struct ata_probe_ent *
 ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port)
 {
-	struct ata_probe_ent *probe_ent = ata_probe_ent_alloc(2, pdev, port);
+	struct ata_probe_ent *probe_ent =
+		ata_probe_ent_alloc(2, pci_dev_to_dev(pdev), port);
 	if (!probe_ent)
 		return NULL;
 
@@ -3538,7 +3691,8 @@ err_out:
 
 void ata_pci_remove_one (struct pci_dev *pdev)
 {
-	struct ata_host_set *host_set = pci_get_drvdata(pdev);
+	struct device *dev = pci_dev_to_dev(pdev);
+	struct ata_host_set *host_set = dev_get_drvdata(dev);
 	struct ata_port *ap;
 	unsigned int i;
 	Scsi_Host_Template *sht;
@@ -3577,7 +3731,7 @@ void ata_pci_remove_one (struct pci_dev 
 
 	kfree(host_set);
 	pci_disable_device(pdev);
-	pci_set_drvdata(pdev, NULL);
+	dev_set_drvdata(dev, NULL);
 }
 
 /**
@@ -3628,6 +3782,7 @@ int pci_test_config_bits(struct pci_dev 
 
 	return (tmp == bits->val) ? 1 : 0;
 }
+#endif /* CONFIG_PCI */
 
 
 /**
@@ -3659,7 +3814,6 @@ module_exit(ata_exit);
  * Do not depend on ABI/API stability.
  */
 
-EXPORT_SYMBOL_GPL(pci_test_config_bits);
 EXPORT_SYMBOL_GPL(ata_std_bios_param);
 EXPORT_SYMBOL_GPL(ata_std_ports);
 EXPORT_SYMBOL_GPL(ata_device_add);
@@ -3674,8 +3828,6 @@ EXPORT_SYMBOL_GPL(ata_noop_dev_select);
 EXPORT_SYMBOL_GPL(ata_std_dev_select);
 EXPORT_SYMBOL_GPL(ata_tf_to_fis);
 EXPORT_SYMBOL_GPL(ata_tf_from_fis);
-EXPORT_SYMBOL_GPL(ata_pci_init_legacy_mode);
-EXPORT_SYMBOL_GPL(ata_pci_init_native_mode);
 EXPORT_SYMBOL_GPL(ata_check_status);
 EXPORT_SYMBOL_GPL(ata_exec_command);
 EXPORT_SYMBOL_GPL(ata_port_start);
@@ -3690,15 +3842,23 @@ EXPORT_SYMBOL_GPL(sata_phy_reset);
 EXPORT_SYMBOL_GPL(__sata_phy_reset);
 EXPORT_SYMBOL_GPL(ata_bus_reset);
 EXPORT_SYMBOL_GPL(ata_port_disable);
-EXPORT_SYMBOL_GPL(ata_pci_init_one);
-EXPORT_SYMBOL_GPL(ata_pci_remove_one);
 EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
 EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
 EXPORT_SYMBOL_GPL(ata_scsi_error);
 EXPORT_SYMBOL_GPL(ata_scsi_detect);
 EXPORT_SYMBOL_GPL(ata_add_to_probe_list);
 EXPORT_SYMBOL_GPL(libata_msleep);
+EXPORT_SYMBOL_GPL(ssleep);
 EXPORT_SYMBOL_GPL(ata_scsi_release);
 EXPORT_SYMBOL_GPL(ata_host_intr);
 EXPORT_SYMBOL_GPL(ata_dev_classify);
 EXPORT_SYMBOL_GPL(ata_dev_id_string);
+EXPORT_SYMBOL_GPL(ata_scsi_simulate);
+
+#ifdef CONFIG_PCI
+EXPORT_SYMBOL_GPL(pci_test_config_bits);
+EXPORT_SYMBOL_GPL(ata_pci_init_legacy_mode);
+EXPORT_SYMBOL_GPL(ata_pci_init_native_mode);
+EXPORT_SYMBOL_GPL(ata_pci_init_one);
+EXPORT_SYMBOL_GPL(ata_pci_remove_one);
+#endif /* CONFIG_PCI */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/scsi/libata-scsi.c linux-2.4.29-pre3/drivers/scsi/libata-scsi.c
--- linux-2.4.28/drivers/scsi/libata-scsi.c	2004-12-22 16:17:18.439159512 +0000
+++ linux-2.4.29-pre3/drivers/scsi/libata-scsi.c	2004-12-22 16:05:45.390518920 +0000
@@ -36,9 +36,6 @@
 #include "libata.h"
 
 typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, u8 *scsicmd);
-static void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev,
-			      struct scsi_cmnd *cmd,
-			      void (*done)(struct scsi_cmnd *));
 static struct ata_device *
 ata_scsi_find_dev(struct ata_port *ap, struct scsi_device *scsidev);
 
@@ -101,7 +98,7 @@ int ata_scsi_ioctl(struct scsi_device *s
 		return 0;
 
 	default:
-		rc = -EOPNOTSUPP;
+		rc = -ENOTTY;
 		break;
 	}
 
@@ -160,6 +157,7 @@ struct ata_queued_cmd *ata_scsi_qc_new(s
 /**
  *	ata_to_sense_error - convert ATA error to SCSI error
  *	@qc: Command that we are erroring out
+ *	@drv_stat: value contained in ATA status register
  *
  *	Converts an ATA error into a SCSI error. While we are at it
  *	we decode and dump the ATA error for the user so that they
@@ -373,7 +371,7 @@ static unsigned int ata_scsi_flush_xlat(
 	tf->protocol = ATA_PROT_NODATA;
 
 	if ((tf->flags & ATA_TFLAG_LBA48) &&
-	    (ata_id_has_flush_ext(qc->dev)))
+	    (ata_id_has_flush_ext(qc->dev->id)))
 		tf->command = ATA_CMD_FLUSH_EXT;
 	else
 		tf->command = ATA_CMD_FLUSH;
@@ -643,7 +641,7 @@ static void ata_scsi_translate(struct at
 			ata_sg_init_one(qc, cmd->request_buffer,
 					cmd->request_bufflen);
 
-		qc->pci_dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
+		qc->dma_dir = cmd->sc_data_direction;
 	}
 
 	qc->complete_fn = ata_scsi_qc_complete;
@@ -700,6 +698,7 @@ static unsigned int ata_scsi_rbuf_get(st
 /**
  *	ata_scsi_rbuf_put - Unmap response buffer.
  *	@cmd: SCSI command containing buffer to be unmapped.
+ *	@buf: buffer to unmap
  *
  *	Unmaps response buffer contained within @cmd.
  *
@@ -707,19 +706,19 @@ static unsigned int ata_scsi_rbuf_get(st
  *	spin_lock_irqsave(host_set lock)
  */
 
-static inline void ata_scsi_rbuf_put(struct scsi_cmnd *cmd)
+static inline void ata_scsi_rbuf_put(struct scsi_cmnd *cmd, u8 *buf)
 {
 	if (cmd->use_sg) {
 		struct scatterlist *sg;
 
 		sg = (struct scatterlist *) cmd->request_buffer;
-		kunmap_atomic(sg->page, KM_USER0);
+		kunmap_atomic(buf - sg->offset, KM_USER0);
 	}
 }
 
 /**
  *	ata_scsi_rbuf_fill - wrapper for SCSI command simulators
- *	@args: Port / device / SCSI command of interest.
+ *	@args: device IDENTIFY data / SCSI command of interest.
  *	@actor: Callback hook for desired SCSI command simulator
  *
  *	Takes care of the hard work of simulating a SCSI command...
@@ -743,7 +742,7 @@ void ata_scsi_rbuf_fill(struct ata_scsi_
 	buflen = ata_scsi_rbuf_get(cmd, &rbuf);
 	memset(rbuf, 0, buflen);
 	rc = actor(args, rbuf, buflen);
-	ata_scsi_rbuf_put(cmd);
+	ata_scsi_rbuf_put(cmd, rbuf);
 
 	if (rc)
 		ata_bad_cdb(cmd, args->done);
@@ -755,7 +754,7 @@ void ata_scsi_rbuf_fill(struct ata_scsi_
 
 /**
  *	ata_scsiop_inq_std - Simulate INQUIRY command
- *	@args: Port / device / SCSI command of interest.
+ *	@args: device IDENTIFY data / SCSI command of interest.
  *	@rbuf: Response buffer, to which simulated SCSI cmd output is sent.
  *	@buflen: Response buffer length.
  *
@@ -769,8 +768,6 @@ void ata_scsi_rbuf_fill(struct ata_scsi_
 unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
 			       unsigned int buflen)
 {
-	struct ata_device *dev = args->dev;
-
 	u8 hdr[] = {
 		TYPE_DISK,
 		0,
@@ -780,7 +777,7 @@ unsigned int ata_scsiop_inq_std(struct a
 	};
 
 	/* set scsi removeable (RMB) bit per ata bit */
-	if (ata_id_removeable(dev))
+	if (ata_id_removeable(args->id))
 		hdr[1] |= (1 << 7);
 
 	VPRINTK("ENTER\n");
@@ -789,8 +786,8 @@ unsigned int ata_scsiop_inq_std(struct a
 
 	if (buflen > 35) {
 		memcpy(&rbuf[8], "ATA     ", 8);
-		ata_dev_id_string(dev, &rbuf[16], ATA_ID_PROD_OFS, 16);
-		ata_dev_id_string(dev, &rbuf[32], ATA_ID_FW_REV_OFS, 4);
+		ata_dev_id_string(args->id, &rbuf[16], ATA_ID_PROD_OFS, 16);
+		ata_dev_id_string(args->id, &rbuf[32], ATA_ID_FW_REV_OFS, 4);
 		if (rbuf[32] == 0 || rbuf[32] == ' ')
 			memcpy(&rbuf[32], "n/a ", 4);
 	}
@@ -814,7 +811,7 @@ unsigned int ata_scsiop_inq_std(struct a
 
 /**
  *	ata_scsiop_inq_00 - Simulate INQUIRY EVPD page 0, list of pages
- *	@args: Port / device / SCSI command of interest.
+ *	@args: device IDENTIFY data / SCSI command of interest.
  *	@rbuf: Response buffer, to which simulated SCSI cmd output is sent.
  *	@buflen: Response buffer length.
  *
@@ -842,7 +839,7 @@ unsigned int ata_scsiop_inq_00(struct at
 
 /**
  *	ata_scsiop_inq_80 - Simulate INQUIRY EVPD page 80, device serial number
- *	@args: Port / device / SCSI command of interest.
+ *	@args: device IDENTIFY data / SCSI command of interest.
  *	@rbuf: Response buffer, to which simulated SCSI cmd output is sent.
  *	@buflen: Response buffer length.
  *
@@ -863,8 +860,8 @@ unsigned int ata_scsiop_inq_80(struct at
 	};
 	memcpy(rbuf, hdr, sizeof(hdr));
 
-	if (buflen > (ATA_SERNO_LEN + 4))
-		ata_dev_id_string(args->dev, (unsigned char *) &rbuf[4],
+	if (buflen > (ATA_SERNO_LEN + 4 - 1))
+		ata_dev_id_string(args->id, (unsigned char *) &rbuf[4],
 				  ATA_ID_SERNO_OFS, ATA_SERNO_LEN);
 
 	return 0;
@@ -874,7 +871,7 @@ static const char *inq_83_str = "Linux A
 
 /**
  *	ata_scsiop_inq_83 - Simulate INQUIRY EVPD page 83, device identity
- *	@args: Port / device / SCSI command of interest.
+ *	@args: device IDENTIFY data / SCSI command of interest.
  *	@rbuf: Response buffer, to which simulated SCSI cmd output is sent.
  *	@buflen: Response buffer length.
  *
@@ -892,7 +889,7 @@ unsigned int ata_scsiop_inq_83(struct at
 	rbuf[3] = 4 + strlen(inq_83_str);	/* page len */
 
 	/* our one and only identification descriptor (vendor-specific) */
-	if (buflen > (strlen(inq_83_str) + 4 + 4)) {
+	if (buflen > (strlen(inq_83_str) + 4 + 4 - 1)) {
 		rbuf[4 + 0] = 2;	/* code set: ASCII */
 		rbuf[4 + 3] = strlen(inq_83_str);
 		memcpy(rbuf + 4 + 4, inq_83_str, strlen(inq_83_str));
@@ -903,7 +900,7 @@ unsigned int ata_scsiop_inq_83(struct at
 
 /**
  *	ata_scsiop_noop -
- *	@args: Port / device / SCSI command of interest.
+ *	@args: device IDENTIFY data / SCSI command of interest.
  *	@rbuf: Response buffer, to which simulated SCSI cmd output is sent.
  *	@buflen: Response buffer length.
  *
@@ -951,7 +948,7 @@ static void ata_msense_push(u8 **ptr_io,
 
 /**
  *	ata_msense_caching - Simulate MODE SENSE caching info page
- *	@dev: Device associated with this MODE SENSE command
+ *	@id: device IDENTIFY data
  *	@ptr_io: (input/output) Location to store more output data
  *	@last: End of output data buffer
  *
@@ -963,7 +960,7 @@ static void ata_msense_push(u8 **ptr_io,
  *	None.
  */
 
-static unsigned int ata_msense_caching(struct ata_device *dev, u8 **ptr_io,
+static unsigned int ata_msense_caching(u16 *id, u8 **ptr_io,
 				       const u8 *last)
 {
 	u8 page[] = {
@@ -973,9 +970,9 @@ static unsigned int ata_msense_caching(s
 		0, 0, 0, 0, 0, 0, 0, 0		/* 8 zeroes */
 	};
 
-	if (ata_id_wcache_enabled(dev))
+	if (ata_id_wcache_enabled(id))
 		page[2] |= (1 << 2);	/* write cache enable */
-	if (!ata_id_rahead_enabled(dev))
+	if (!ata_id_rahead_enabled(id))
 		page[12] |= (1 << 5);	/* disable read ahead */
 
 	ata_msense_push(ptr_io, last, page, sizeof(page));
@@ -1029,7 +1026,7 @@ static unsigned int ata_msense_rw_recove
 
 /**
  *	ata_scsiop_mode_sense - Simulate MODE SENSE 6, 10 commands
- *	@args: Port / device / SCSI command of interest.
+ *	@args: device IDENTIFY data / SCSI command of interest.
  *	@rbuf: Response buffer, to which simulated SCSI cmd output is sent.
  *	@buflen: Response buffer length.
  *
@@ -1043,7 +1040,6 @@ unsigned int ata_scsiop_mode_sense(struc
 				  unsigned int buflen)
 {
 	u8 *scsicmd = args->cmd->cmnd, *p, *last;
-	struct ata_device *dev = args->dev;
 	unsigned int page_control, six_byte, output_len;
 
 	VPRINTK("ENTER\n");
@@ -1071,7 +1067,7 @@ unsigned int ata_scsiop_mode_sense(struc
 		break;
 
 	case 0x08:		/* caching */
-		output_len += ata_msense_caching(dev, &p, last);
+		output_len += ata_msense_caching(args->id, &p, last);
 		break;
 
 	case 0x0a: {		/* control mode */
@@ -1081,7 +1077,7 @@ unsigned int ata_scsiop_mode_sense(struc
 
 	case 0x3f:		/* all pages */
 		output_len += ata_msense_rw_recovery(&p, last);
-		output_len += ata_msense_caching(dev, &p, last);
+		output_len += ata_msense_caching(args->id, &p, last);
 		output_len += ata_msense_ctl_mode(&p, last);
 		break;
 
@@ -1103,7 +1099,7 @@ unsigned int ata_scsiop_mode_sense(struc
 
 /**
  *	ata_scsiop_read_cap - Simulate READ CAPACITY[ 16] commands
- *	@args: Port / device / SCSI command of interest.
+ *	@args: device IDENTIFY data / SCSI command of interest.
  *	@rbuf: Response buffer, to which simulated SCSI cmd output is sent.
  *	@buflen: Response buffer length.
  *
@@ -1116,11 +1112,15 @@ unsigned int ata_scsiop_mode_sense(struc
 unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf,
 			        unsigned int buflen)
 {
-	u64 n_sectors = args->dev->n_sectors;
+	u64 n_sectors;
 	u32 tmp;
 
 	VPRINTK("ENTER\n");
 
+	if (ata_id_has_lba48(args->id))
+		n_sectors = ata_id_u64(args->id, 100);
+	else
+		n_sectors = ata_id_u32(args->id, 60);
 	n_sectors--;		/* ATA TotalUserSectors - 1 */
 
 	tmp = n_sectors;	/* note: truncates, if lba48 */
@@ -1158,7 +1158,7 @@ unsigned int ata_scsiop_read_cap(struct 
 
 /**
  *	ata_scsiop_report_luns - Simulate REPORT LUNS command
- *	@args: Port / device / SCSI command of interest.
+ *	@args: device IDENTIFY data / SCSI command of interest.
  *	@rbuf: Response buffer, to which simulated SCSI cmd output is sent.
  *	@buflen: Response buffer length.
  *
@@ -1210,9 +1210,15 @@ static int atapi_qc_complete(struct ata_
 {
 	struct scsi_cmnd *cmd = qc->scsicmd;
 
-	if (unlikely(drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ)))
+	if (unlikely(drv_stat & (ATA_ERR | ATA_BUSY | ATA_DRQ))) {
+		DPRINTK("request check condition\n");
+
 		cmd->result = SAM_STAT_CHECK_CONDITION;
-	else {
+
+		qc->scsidone(cmd);
+
+		return 1;
+	} else {
 		u8 *scsicmd = cmd->cmnd;
 
 		if (scsicmd[0] == INQUIRY) {
@@ -1222,7 +1228,7 @@ static int atapi_qc_complete(struct ata_
 			buflen = ata_scsi_rbuf_get(cmd, &buf);
 			buf[2] = 0x5;
 			buf[3] = (buf[3] & 0xf0) | 2;
-			ata_scsi_rbuf_put(cmd);
+			ata_scsi_rbuf_put(cmd, buf);
 		}
 		cmd->result = SAM_STAT_GOOD;
 	}
@@ -1284,13 +1290,15 @@ static unsigned int atapi_xlat(struct at
 #endif
 	}
 
+	qc->nbytes = cmd->bufflen;
+
 	return 0;
 }
 
 /**
  *	ata_scsi_find_dev - lookup ata_device from scsi_cmnd
  *	@ap: ATA port to which the device is attached
- *	@cmd: SCSI command to be sent to the device
+ *	@scsidev: SCSI device from which we derive the ATA device
  *
  *	Given various information provided in struct scsi_cmnd,
  *	map that onto an ATA bus, and using that mapping
@@ -1439,7 +1447,7 @@ int ata_scsi_queuecmd(struct scsi_cmnd *
 		if (xlat_func)
 			ata_scsi_translate(ap, dev, cmd, done, xlat_func);
 		else
-			ata_scsi_simulate(ap, dev, cmd, done);
+			ata_scsi_simulate(dev->id, cmd, done);
 	} else
 		ata_scsi_translate(ap, dev, cmd, done, atapi_xlat);
 
@@ -1451,8 +1459,7 @@ out_unlock:
 
 /**
  *	ata_scsi_simulate - simulate SCSI command on ATA device
- *	@ap: Port to which ATA device is attached.
- *	@dev: Target device for CDB.
+ *	@id: current IDENTIFY data for target device.
  *	@cmd: SCSI command being sent to device.
  *	@done: SCSI command completion function.
  *
@@ -1463,15 +1470,14 @@ out_unlock:
  *	spin_lock_irqsave(host_set lock)
  */
 
-static void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev,
-			      struct scsi_cmnd *cmd,
-			      void (*done)(struct scsi_cmnd *))
+void ata_scsi_simulate(u16 *id,
+		      struct scsi_cmnd *cmd,
+		      void (*done)(struct scsi_cmnd *))
 {
 	struct ata_scsi_args args;
 	u8 *scsicmd = cmd->cmnd;
 
-	args.ap = ap;
-	args.dev = dev;
+	args.id = id;
 	args.cmd = cmd;
 	args.done = done;
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/scsi/libata.h linux-2.4.29-pre3/drivers/scsi/libata.h
--- linux-2.4.28/drivers/scsi/libata.h	2004-12-22 16:17:18.440159360 +0000
+++ linux-2.4.29-pre3/drivers/scsi/libata.h	2004-12-22 16:06:00.739185568 +0000
@@ -26,12 +26,11 @@
 #define __LIBATA_H__
 
 #define DRV_NAME	"libata"
-#define DRV_VERSION	"1.02"	/* must be exactly four chars */
+#define DRV_VERSION	"1.10"	/* must be exactly four chars */
 
 struct ata_scsi_args {
-	struct ata_port		*ap;
-	struct ata_device	*dev;
-	struct scsi_cmnd		*cmd;
+	u16			*id;
+	struct scsi_cmnd	*cmd;
 	void			(*done)(struct scsi_cmnd *);
 };
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/scsi/sata_nv.c linux-2.4.29-pre3/drivers/scsi/sata_nv.c
--- linux-2.4.28/drivers/scsi/sata_nv.c	2004-12-22 16:17:18.540144160 +0000
+++ linux-2.4.29-pre3/drivers/scsi/sata_nv.c	2004-12-22 16:07:43.335588544 +0000
@@ -44,7 +44,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME			"sata_nv"
-#define DRV_VERSION			"0.03"
+#define DRV_VERSION			"0.5"
 
 #define NV_PORTS			2
 #define NV_PIO_MASK			0x1f
@@ -235,6 +235,7 @@ MODULE_AUTHOR("NVIDIA");
 MODULE_DESCRIPTION("low-level driver for NVIDIA nForce SATA controller");
 MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(pci, nv_pci_tbl);
+MODULE_VERSION(DRV_VERSION);
 
 irqreturn_t nv_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
 {
@@ -379,9 +380,6 @@ static int nv_init_one (struct pci_dev *
 
 	return 0;
 
-err_out_iounmap:
-	if (host->host_desc->host_flags & NV_HOST_FLAGS_SCR_MMIO)
-		iounmap(probe_ent->mmio_base);
 err_out_free_host:
 	kfree(host);
 err_out_free_ent:
@@ -448,12 +446,13 @@ static void nv_check_hotplug(struct ata_
 
 static void nv_enable_hotplug_ck804(struct ata_probe_ent *probe_ent)
 {
+	struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
 	u8 intr_mask;
 	u8 regval;
 
-	pci_read_config_byte(probe_ent->pdev, NV_MCP_SATA_CFG_20, &regval);
+	pci_read_config_byte(pdev, NV_MCP_SATA_CFG_20, &regval);
 	regval |= NV_MCP_SATA_CFG_20_SATA_SPACE_EN;
-	pci_write_config_byte(probe_ent->pdev, NV_MCP_SATA_CFG_20, regval);
+	pci_write_config_byte(pdev, NV_MCP_SATA_CFG_20, regval);
 
 	writeb(NV_INT_STATUS_HOTPLUG, probe_ent->mmio_base + NV_INT_STATUS_CK804);
 
@@ -465,6 +464,7 @@ static void nv_enable_hotplug_ck804(stru
 
 static void nv_disable_hotplug_ck804(struct ata_host_set *host_set)
 {
+	struct pci_dev *pdev = to_pci_dev(host_set->dev);
 	u8 intr_mask;
 	u8 regval;
 
@@ -474,9 +474,9 @@ static void nv_disable_hotplug_ck804(str
 
 	writeb(intr_mask, host_set->mmio_base + NV_INT_ENABLE_CK804);
 
-	pci_read_config_byte(host_set->pdev, NV_MCP_SATA_CFG_20, &regval);
+	pci_read_config_byte(pdev, NV_MCP_SATA_CFG_20, &regval);
 	regval &= ~NV_MCP_SATA_CFG_20_SATA_SPACE_EN;
-	pci_write_config_byte(host_set->pdev, NV_MCP_SATA_CFG_20, regval);
+	pci_write_config_byte(pdev, NV_MCP_SATA_CFG_20, regval);
 }
 
 static void nv_check_hotplug_ck804(struct ata_host_set *host_set)
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/scsi/sata_promise.c linux-2.4.29-pre3/drivers/scsi/sata_promise.c
--- linux-2.4.28/drivers/scsi/sata_promise.c	2004-12-22 16:17:18.553142184 +0000
+++ linux-2.4.29-pre3/drivers/scsi/sata_promise.c	2004-12-22 16:05:31.470635064 +0000
@@ -40,7 +40,7 @@
 #include "sata_promise.h"
 
 #define DRV_NAME	"sata_promise"
-#define DRV_VERSION	"1.00"
+#define DRV_VERSION	"1.01"
 
 #define msleep libata_msleep	/* 2.4-specific */
 
@@ -74,7 +74,7 @@ struct pdc_port_priv {
 
 static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg);
 static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
-static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
+static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
 static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
 static void pdc_eng_timeout(struct ata_port *ap);
 static int pdc_port_start(struct ata_port *ap);
@@ -86,7 +86,7 @@ static void pdc_exec_command_mmio(struct
 static void pdc_irq_clear(struct ata_port *ap);
 static int pdc_qc_issue_prot(struct ata_queued_cmd *qc);
 
-static Scsi_Host_Template pdc_sata_sht = {
+static Scsi_Host_Template pdc_ata_sht = {
 	.module			= THIS_MODULE,
 	.name			= DRV_NAME,
 	.detect			= ata_scsi_detect,
@@ -106,7 +106,7 @@ static Scsi_Host_Template pdc_sata_sht =
 	.bios_param		= ata_std_bios_param,
 };
 
-static struct ata_port_operations pdc_sata_ops = {
+static struct ata_port_operations pdc_ata_ops = {
 	.port_disable		= ata_port_disable,
 	.tf_load		= pdc_tf_load_mmio,
 	.tf_read		= ata_tf_read,
@@ -128,28 +128,28 @@ static struct ata_port_operations pdc_sa
 static struct ata_port_info pdc_port_info[] = {
 	/* board_2037x */
 	{
-		.sht		= &pdc_sata_sht,
+		.sht		= &pdc_ata_sht,
 		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
 				  ATA_FLAG_SRST | ATA_FLAG_MMIO,
 		.pio_mask	= 0x1f, /* pio0-4 */
 		.mwdma_mask	= 0x07, /* mwdma0-2 */
 		.udma_mask	= 0x7f, /* udma0-6 ; FIXME */
-		.port_ops	= &pdc_sata_ops,
+		.port_ops	= &pdc_ata_ops,
 	},
 
 	/* board_20319 */
 	{
-		.sht		= &pdc_sata_sht,
+		.sht		= &pdc_ata_sht,
 		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
 				  ATA_FLAG_SRST | ATA_FLAG_MMIO,
 		.pio_mask	= 0x1f, /* pio0-4 */
 		.mwdma_mask	= 0x07, /* mwdma0-2 */
 		.udma_mask	= 0x7f, /* udma0-6 ; FIXME */
-		.port_ops	= &pdc_sata_ops,
+		.port_ops	= &pdc_ata_ops,
 	},
 };
 
-static struct pci_device_id pdc_sata_pci_tbl[] = {
+static struct pci_device_id pdc_ata_pci_tbl[] = {
 	{ PCI_VENDOR_ID_PROMISE, 0x3371, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 	  board_2037x },
 	{ PCI_VENDOR_ID_PROMISE, 0x3373, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
@@ -166,17 +166,17 @@ static struct pci_device_id pdc_sata_pci
 };
 
 
-static struct pci_driver pdc_sata_pci_driver = {
+static struct pci_driver pdc_ata_pci_driver = {
 	.name			= DRV_NAME,
-	.id_table		= pdc_sata_pci_tbl,
-	.probe			= pdc_sata_init_one,
+	.id_table		= pdc_ata_pci_tbl,
+	.probe			= pdc_ata_init_one,
 	.remove			= ata_pci_remove_one,
 };
 
 
 static int pdc_port_start(struct ata_port *ap)
 {
-	struct pci_dev *pdev = ap->host_set->pdev;
+	struct device *dev = ap->host_set->dev;
 	struct pdc_port_priv *pp;
 	int rc;
 
@@ -191,7 +191,7 @@ static int pdc_port_start(struct ata_por
 	}
 	memset(pp, 0, sizeof(*pp));
 
-	pp->pkt = pci_alloc_consistent(pdev, 128, &pp->pkt_dma);
+	pp->pkt = dma_alloc_coherent(dev, 128, &pp->pkt_dma, GFP_KERNEL);
 	if (!pp->pkt) {
 		rc = -ENOMEM;
 		goto err_out_kfree;
@@ -211,11 +211,11 @@ err_out:
 
 static void pdc_port_stop(struct ata_port *ap)
 {
-	struct pci_dev *pdev = ap->host_set->pdev;
+	struct device *dev = ap->host_set->dev;
 	struct pdc_port_priv *pp = ap->private_data;
 
 	ap->private_data = NULL;
-	pci_free_consistent(pdev, 128, pp->pkt, pp->pkt_dma);
+	dma_free_coherent(dev, 128, pp->pkt, pp->pkt_dma);
 	kfree(pp);
 	ata_port_stop(ap);
 }
@@ -483,7 +483,7 @@ static void pdc_exec_command_mmio(struct
 }
 
 
-static void pdc_sata_setup_port(struct ata_ioports *port, unsigned long base)
+static void pdc_ata_setup_port(struct ata_ioports *port, unsigned long base)
 {
 	port->cmd_addr		= base;
 	port->data_addr		= base;
@@ -541,7 +541,7 @@ static void pdc_host_init(unsigned int c
 	writel(tmp, mmio + PDC_SLEW_CTL);
 }
 
-static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
+static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
 	static int printed_version;
 	struct ata_probe_ent *probe_ent = NULL;
@@ -576,7 +576,7 @@ static int pdc_sata_init_one (struct pci
 	}
 
 	memset(probe_ent, 0, sizeof(*probe_ent));
-	probe_ent->pdev = pdev;
+	probe_ent->dev = pci_dev_to_dev(pdev);
 	INIT_LIST_HEAD(&probe_ent->node);
 
 	mmio_base = ioremap(pci_resource_start(pdev, 3),
@@ -598,8 +598,8 @@ static int pdc_sata_init_one (struct pci
        	probe_ent->irq_flags = SA_SHIRQ;
 	probe_ent->mmio_base = mmio_base;
 
-	pdc_sata_setup_port(&probe_ent->port[0], base + 0x200);
-	pdc_sata_setup_port(&probe_ent->port[1], base + 0x280);
+	pdc_ata_setup_port(&probe_ent->port[0], base + 0x200);
+	pdc_ata_setup_port(&probe_ent->port[1], base + 0x280);
 
 	probe_ent->port[0].scr_addr = base + 0x400;
 	probe_ent->port[1].scr_addr = base + 0x500;
@@ -609,8 +609,8 @@ static int pdc_sata_init_one (struct pci
 	case board_20319:
        		probe_ent->n_ports = 4;
 
-		pdc_sata_setup_port(&probe_ent->port[2], base + 0x300);
-		pdc_sata_setup_port(&probe_ent->port[3], base + 0x380);
+		pdc_ata_setup_port(&probe_ent->port[2], base + 0x300);
+		pdc_ata_setup_port(&probe_ent->port[3], base + 0x380);
 
 		probe_ent->port[2].scr_addr = base + 0x600;
 		probe_ent->port[3].scr_addr = base + 0x700;
@@ -642,15 +642,15 @@ err_out:
 }
 
 
-static int __init pdc_sata_init(void)
+static int __init pdc_ata_init(void)
 {
 	int rc;
 
-	rc = pci_module_init(&pdc_sata_pci_driver);
+	rc = pci_module_init(&pdc_ata_pci_driver);
 	if (rc)
 		return rc;
 
-	rc = scsi_register_module(MODULE_SCSI_HA, &pdc_sata_sht);
+	rc = scsi_register_module(MODULE_SCSI_HA, &pdc_ata_sht);
 	if (rc) {
 		rc = -ENODEV;
 		goto err_out;
@@ -659,22 +659,23 @@ static int __init pdc_sata_init(void)
 	return 0;
 
 err_out:
-	pci_unregister_driver(&pdc_sata_pci_driver);
+	pci_unregister_driver(&pdc_ata_pci_driver);
 	return rc;
 }
 
 
-static void __exit pdc_sata_exit(void)
+static void __exit pdc_ata_exit(void)
 {
-	scsi_unregister_module(MODULE_SCSI_HA, &pdc_sata_sht);
-	pci_unregister_driver(&pdc_sata_pci_driver);
+	scsi_unregister_module(MODULE_SCSI_HA, &pdc_ata_sht);
+	pci_unregister_driver(&pdc_ata_pci_driver);
 }
 
 
 MODULE_AUTHOR("Jeff Garzik");
 MODULE_DESCRIPTION("Promise SATA TX2/TX4 low-level driver");
 MODULE_LICENSE("GPL");
-MODULE_DEVICE_TABLE(pci, pdc_sata_pci_tbl);
+MODULE_DEVICE_TABLE(pci, pdc_ata_pci_tbl);
+MODULE_VERSION(DRV_VERSION);
 
-module_init(pdc_sata_init);
-module_exit(pdc_sata_exit);
+module_init(pdc_ata_init);
+module_exit(pdc_ata_exit);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/scsi/sata_sil.c linux-2.4.29-pre3/drivers/scsi/sata_sil.c
--- linux-2.4.28/drivers/scsi/sata_sil.c	2004-12-22 16:17:18.554142032 +0000
+++ linux-2.4.29-pre3/drivers/scsi/sata_sil.c	2004-12-22 16:06:49.227814176 +0000
@@ -38,7 +38,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME	"sata_sil"
-#define DRV_VERSION	"0.54"
+#define DRV_VERSION	"0.8"
 
 enum {
 	sil_3112		= 0,
@@ -87,6 +87,7 @@ struct sil_drivelist {
 	{ "ST380023AS",		SIL_QUIRK_MOD15WRITE },
 	{ "ST3120023AS",	SIL_QUIRK_MOD15WRITE },
 	{ "ST3160023AS",	SIL_QUIRK_MOD15WRITE },
+	{ "ST3120026AS",	SIL_QUIRK_MOD15WRITE },
 	{ "ST340014ASL",	SIL_QUIRK_MOD15WRITE },
 	{ "ST360014ASL",	SIL_QUIRK_MOD15WRITE },
 	{ "ST380011ASL",	SIL_QUIRK_MOD15WRITE },
@@ -190,6 +191,7 @@ MODULE_AUTHOR("Jeff Garzik");
 MODULE_DESCRIPTION("low-level driver for Silicon Image SATA controller");
 MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(pci, sil_pci_tbl);
+MODULE_VERSION(DRV_VERSION);
 
 static void sil_post_set_mode (struct ata_port *ap)
 {
@@ -288,7 +290,7 @@ static void sil_dev_config(struct ata_po
 	const char *s;
 	unsigned int len;
 
-	ata_dev_id_string(dev, model_num, ATA_ID_PROD_OFS,
+	ata_dev_id_string(dev->id, model_num, ATA_ID_PROD_OFS,
 			  sizeof(model_num));
 	s = &model_num[0];
 	len = strnlen(s, sizeof(model_num));
@@ -360,7 +362,7 @@ static int sil_init_one (struct pci_dev 
 
 	memset(probe_ent, 0, sizeof(*probe_ent));
 	INIT_LIST_HEAD(&probe_ent->node);
-	probe_ent->pdev = pdev;
+	probe_ent->dev = pci_dev_to_dev(pdev);
 	probe_ent->port_ops = sil_port_info[ent->driver_data].port_ops;
 	probe_ent->sht = sil_port_info[ent->driver_data].sht;
 	probe_ent->n_ports = (ent->driver_data == sil_3114) ? 4 : 2;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/scsi/sata_sis.c linux-2.4.29-pre3/drivers/scsi/sata_sis.c
--- linux-2.4.28/drivers/scsi/sata_sis.c	2004-12-22 16:17:18.555141880 +0000
+++ linux-2.4.29-pre3/drivers/scsi/sata_sis.c	2004-12-22 16:06:34.169103448 +0000
@@ -38,7 +38,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME	"sata_sis"
-#define DRV_VERSION	"0.10"
+#define DRV_VERSION	"0.5"
 
 enum {
 	sis_180			= 0,
@@ -129,6 +129,7 @@ MODULE_AUTHOR("Uwe Koziolek");
 MODULE_DESCRIPTION("low-level driver for Silicon Integratad Systems SATA controller");
 MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(pci, sis_pci_tbl);
+MODULE_VERSION(DRV_VERSION);
 
 static unsigned int get_scr_cfg_addr(unsigned int port_no, unsigned int sc_reg)
 {
@@ -141,22 +142,24 @@ static unsigned int get_scr_cfg_addr(uns
 
 static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
 {
+	struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
 	unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, sc_reg);
 	u32 val;
 
 	if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */
 		return 0xffffffff;
-	pci_read_config_dword(ap->host_set->pdev, cfg_addr, &val);
+	pci_read_config_dword(pdev, cfg_addr, &val);
 	return val;
 }
 
 static void sis_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val)
 {
+	struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
 	unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, scr);
 
 	if (scr == SCR_ERROR) /* doesn't exist in PCI cfg space */
 		return;
-	pci_write_config_dword(ap->host_set->pdev, cfg_addr, val);
+	pci_write_config_dword(pdev, cfg_addr, val);
 }
 
 static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg)
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/scsi/sata_svw.c linux-2.4.29-pre3/drivers/scsi/sata_svw.c
--- linux-2.4.28/drivers/scsi/sata_svw.c	2004-12-22 16:17:18.562140816 +0000
+++ linux-2.4.29-pre3/drivers/scsi/sata_svw.c	2004-12-22 16:07:09.622713680 +0000
@@ -49,7 +49,7 @@
 #endif /* CONFIG_PPC_OF */
 
 #define DRV_NAME	"sata_svw"
-#define DRV_VERSION	"1.04"
+#define DRV_VERSION	"1.05"
 
 /* Taskfile registers offsets */
 #define K2_SATA_TF_CMD_OFFSET		0x00
@@ -245,7 +245,7 @@ static int k2_sata_proc_info(struct Scsi
 		return 0;
 
 	/* Find the OF node for the PCI device proper */
-	np = pci_device_to_OF_node(ap->host_set->pdev);
+	np = pci_device_to_OF_node(to_pci_dev(ap->host_set->dev));
 	if (np == NULL)
 		return 0;
 
@@ -374,7 +374,7 @@ static int k2_sata_init_one (struct pci_
 	}
 
 	memset(probe_ent, 0, sizeof(*probe_ent));
-	probe_ent->pdev = pdev;
+	probe_ent->dev = pci_dev_to_dev(pdev);
 	INIT_LIST_HEAD(&probe_ent->node);
 
 	mmio_base = ioremap(pci_resource_start(pdev, 5),
@@ -483,6 +483,7 @@ MODULE_AUTHOR("Benjamin Herrenschmidt");
 MODULE_DESCRIPTION("low-level driver for K2 SATA controller");
 MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(pci, k2_sata_pci_tbl);
+MODULE_VERSION(DRV_VERSION);
 
 module_init(k2_sata_init);
 module_exit(k2_sata_exit);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/scsi/sata_sx4.c linux-2.4.29-pre3/drivers/scsi/sata_sx4.c
--- linux-2.4.28/drivers/scsi/sata_sx4.c	2004-12-22 16:17:18.568139904 +0000
+++ linux-2.4.29-pre3/drivers/scsi/sata_sx4.c	2004-12-22 16:06:40.625121984 +0000
@@ -40,7 +40,7 @@
 #include "sata_promise.h"
 
 #define DRV_NAME	"sata_sx4"
-#define DRV_VERSION	"0.50"
+#define DRV_VERSION	"0.7"
 
 
 enum {
@@ -249,7 +249,7 @@ static void pdc20621_host_stop(struct at
 
 static int pdc_port_start(struct ata_port *ap)
 {
-	struct pci_dev *pdev = ap->host_set->pdev;
+	struct device *dev = ap->host_set->dev;
 	struct pdc_port_priv *pp;
 	int rc;
 
@@ -264,7 +264,7 @@ static int pdc_port_start(struct ata_por
 	}
 	memset(pp, 0, sizeof(*pp));
 
-	pp->pkt = pci_alloc_consistent(pdev, 128, &pp->pkt_dma);
+	pp->pkt = dma_alloc_coherent(dev, 128, &pp->pkt_dma, GFP_KERNEL);
 	if (!pp->pkt) {
 		rc = -ENOMEM;
 		goto err_out_kfree;
@@ -284,11 +284,11 @@ err_out:
 
 static void pdc_port_stop(struct ata_port *ap)
 {
-	struct pci_dev *pdev = ap->host_set->pdev;
+	struct device *dev = ap->host_set->dev;
 	struct pdc_port_priv *pp = ap->private_data;
 
 	ap->private_data = NULL;
-	pci_free_consistent(pdev, 128, pp->pkt, pp->pkt_dma);
+	dma_free_coherent(dev, 128, pp->pkt, pp->pkt_dma);
 	kfree(pp);
 	ata_port_stop(ap);
 }
@@ -1397,7 +1397,7 @@ static int pdc_sata_init_one (struct pci
 	}
 
 	memset(probe_ent, 0, sizeof(*probe_ent));
-	probe_ent->pdev = pdev;
+	probe_ent->dev = pci_dev_to_dev(pdev);
 	INIT_LIST_HEAD(&probe_ent->node);
 
 	mmio_base = ioremap(pci_resource_start(pdev, 3),
@@ -1507,6 +1507,7 @@ MODULE_AUTHOR("Jeff Garzik");
 MODULE_DESCRIPTION("Promise SATA low-level driver");
 MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(pci, pdc_sata_pci_tbl);
+MODULE_VERSION(DRV_VERSION);
 
 module_init(pdc_sata_init);
 module_exit(pdc_sata_exit);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/scsi/sata_uli.c linux-2.4.29-pre3/drivers/scsi/sata_uli.c
--- linux-2.4.28/drivers/scsi/sata_uli.c	2004-12-22 16:17:18.579138232 +0000
+++ linux-2.4.29-pre3/drivers/scsi/sata_uli.c	2004-12-22 16:05:31.466635672 +0000
@@ -32,7 +32,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME	"sata_uli"
-#define DRV_VERSION	"0.11"
+#define DRV_VERSION	"0.2"
 
 enum {
 	uli_5289		= 0,
@@ -124,6 +124,7 @@ MODULE_AUTHOR("Peer Chen");
 MODULE_DESCRIPTION("low-level driver for ULi Electronics SATA controller");
 MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(pci, uli_pci_tbl);
+MODULE_VERSION(DRV_VERSION);
 
 static unsigned int get_scr_cfg_addr(unsigned int port_no, unsigned int sc_reg)
 {
@@ -150,18 +151,20 @@ static unsigned int get_scr_cfg_addr(uns
 
 static u32 uli_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
 {
+	struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
 	unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, sc_reg);
 	u32 val;
 
-	pci_read_config_dword(ap->host_set->pdev, cfg_addr, &val);
+	pci_read_config_dword(pdev, cfg_addr, &val);
 	return val;
 }
 
 static void uli_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val)
 {
+	struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
 	unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, scr);
 
-	pci_write_config_dword(ap->host_set->pdev, cfg_addr, val);
+	pci_write_config_dword(pdev, cfg_addr, val);
 }
 
 static u32 uli_scr_read (struct ata_port *ap, unsigned int sc_reg)
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/scsi/sata_via.c linux-2.4.29-pre3/drivers/scsi/sata_via.c
--- linux-2.4.28/drivers/scsi/sata_via.c	2004-12-22 16:17:18.580138080 +0000
+++ linux-2.4.29-pre3/drivers/scsi/sata_via.c	2004-12-22 16:07:41.625848464 +0000
@@ -38,7 +38,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME	"sata_via"
-#define DRV_VERSION	"0.20"
+#define DRV_VERSION	"1.0"
 
 enum {
 	via_sata		= 0,
@@ -139,6 +139,7 @@ MODULE_AUTHOR("Jeff Garzik");
 MODULE_DESCRIPTION("SCSI low-level driver for VIA SATA controllers");
 MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(pci, svia_pci_tbl);
+MODULE_VERSION(DRV_VERSION);
 
 static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg)
 {
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/scsi/sata_vsc.c linux-2.4.29-pre3/drivers/scsi/sata_vsc.c
--- linux-2.4.28/drivers/scsi/sata_vsc.c	2004-12-22 16:17:18.585137320 +0000
+++ linux-2.4.29-pre3/drivers/scsi/sata_vsc.c	2004-12-22 16:06:59.663227752 +0000
@@ -26,7 +26,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME	"sata_vsc"
-#define DRV_VERSION	"0.01"
+#define DRV_VERSION	"1.0"
 
 /* Interrupt register offsets (from chip base address) */
 #define VSC_SATA_INT_STAT_OFFSET	0x00
@@ -291,7 +291,7 @@ static int __devinit vsc_sata_init_one (
 		goto err_out_regions;
 	}
 	memset(probe_ent, 0, sizeof(*probe_ent));
-	probe_ent->pdev = pdev;
+	probe_ent->dev = pci_dev_to_dev(pdev);
 	INIT_LIST_HEAD(&probe_ent->node);
 
 	mmio_base = ioremap(pci_resource_start(pdev, 0),
@@ -331,6 +331,14 @@ static int __devinit vsc_sata_init_one (
 
 	pci_set_master(pdev);
 
+	/* 
+	 * Config offset 0x98 is "Extended Control and Status Register 0"
+	 * Default value is (1 << 28).  All bits except bit 28 are reserved in
+	 * DPA mode.  If bit 28 is set, LED 0 reflects all ports' activity.
+	 * If bit 28 is clear, each port has its own LED.
+	 */
+	pci_write_config_dword(pdev, 0x98, 0);
+
 	ata_add_to_probe_list(probe_ent);
 
 	return 0;
@@ -401,6 +409,7 @@ MODULE_AUTHOR("Jeremy Higdon");
 MODULE_DESCRIPTION("low-level driver for Vitesse VSC7174 SATA controller");
 MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(pci, vsc_sata_pci_tbl);
+MODULE_VERSION(DRV_VERSION);
 
 module_init(vsc_sata_init);
 module_exit(vsc_sata_exit);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/scsi/scsi_error.c linux-2.4.29-pre3/drivers/scsi/scsi_error.c
--- linux-2.4.28/drivers/scsi/scsi_error.c	2004-12-22 16:17:18.602134736 +0000
+++ linux-2.4.29-pre3/drivers/scsi/scsi_error.c	2004-12-22 16:05:31.683602688 +0000
@@ -410,6 +410,7 @@ STATIC int scsi_request_sense(Scsi_Cmnd 
 	{REQUEST_SENSE, 0, 0, 0, 255, 0};
 	unsigned char scsi_result0[256], *scsi_result = NULL;
 	int saved_result;
+	int saved_resid;
 
 	ASSERT_LOCK(&io_request_lock, 0);
 
@@ -436,6 +437,7 @@ STATIC int scsi_request_sense(Scsi_Cmnd 
 	memset((void *) scsi_result, 0, 256);
 
 	saved_result = SCpnt->result;
+	saved_resid = SCpnt->resid;
 	SCpnt->request_buffer = scsi_result;
 	SCpnt->request_bufflen = 256;
 	SCpnt->use_sg = 0;
@@ -461,6 +463,7 @@ STATIC int scsi_request_sense(Scsi_Cmnd 
 	memcpy((void *) SCpnt->cmnd, (void *) SCpnt->data_cmnd,
 	       sizeof(SCpnt->data_cmnd));
 	SCpnt->result = saved_result;
+	SCpnt->resid = saved_resid;
 	SCpnt->request_buffer = SCpnt->buffer;
 	SCpnt->request_bufflen = SCpnt->bufflen;
 	SCpnt->use_sg = SCpnt->old_use_sg;
@@ -484,6 +487,7 @@ STATIC int scsi_test_unit_ready(Scsi_Cmn
 {
 	static unsigned char tur_command[6] =
 	{TEST_UNIT_READY, 0, 0, 0, 0, 0};
+	int saved_resid;
 
 	memcpy((void *) SCpnt->cmnd, (void *) tur_command,
 	       sizeof(tur_command));
@@ -497,6 +501,7 @@ STATIC int scsi_test_unit_ready(Scsi_Cmn
 	 */
 	memset((void *) SCpnt->sense_buffer, 0, sizeof(SCpnt->sense_buffer));
 
+	saved_resid = SCpnt->resid;
 	SCpnt->request_buffer = NULL;
 	SCpnt->request_bufflen = 0;
 	SCpnt->use_sg = 0;
@@ -512,6 +517,7 @@ STATIC int scsi_test_unit_ready(Scsi_Cmn
 	 */
 	memcpy((void *) SCpnt->cmnd, (void *) SCpnt->data_cmnd,
 	       sizeof(SCpnt->data_cmnd));
+	SCpnt->resid = saved_resid;
 	SCpnt->request_buffer = SCpnt->buffer;
 	SCpnt->request_bufflen = SCpnt->bufflen;
 	SCpnt->use_sg = SCpnt->old_use_sg;
@@ -1366,6 +1372,7 @@ STATIC int scsi_unjam_host(struct Scsi_H
 
 	for (SDpnt = host->host_queue; SDpnt; SDpnt = SDpnt->next) {
 		for (SCpnt = SDpnt->device_queue; SCpnt; SCpnt = SCpnt->next) {
+		      recheck_sense_valid:
 			if (SCpnt->state != SCSI_STATE_FAILED || scsi_sense_valid(SCpnt)) {
 				continue;
 			}
@@ -1402,7 +1409,8 @@ STATIC int scsi_unjam_host(struct Scsi_H
 			SCpnt->state = NEEDS_RETRY;
 			rtn = scsi_eh_retry_command(SCpnt);
 			if (rtn != SUCCESS) {
-				continue;
+				SCpnt->state = SCSI_STATE_FAILED;
+				goto recheck_sense_valid;
 			}
 			/*
 			 * We eventually hand this one back to the top level.
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/scsi/sg.c linux-2.4.29-pre3/drivers/scsi/sg.c
--- linux-2.4.28/drivers/scsi/sg.c	2004-12-22 16:17:18.639129112 +0000
+++ linux-2.4.29-pre3/drivers/scsi/sg.c	2004-12-22 16:06:38.625425984 +0000
@@ -1253,7 +1253,6 @@ static void sg_cmd_done_bh(Scsi_Cmnd * S
     SRpnt->sr_request.rq_dev = MKDEV(0, 0);  /* "sg" _disowns_ request blk */
 
     srp->my_cmdp = NULL;
-    srp->done = 1;
     read_unlock(&sg_dev_arr_lock);
 
     SCSI_LOG_TIMEOUT(4, printk("sg...bh: dev=%d, pack_id=%d, res=0x%x\n",
@@ -1316,8 +1315,9 @@ static void sg_cmd_done_bh(Scsi_Cmnd * S
     }
     if (sfp && srp) {
 	/* Now wake up any sg_read() that is waiting for this packet. */
-	wake_up_interruptible(&sfp->read_wait);
 	kill_fasync(&sfp->async_qp, SIGPOLL, POLL_IN);
+	srp->done = 1;
+	wake_up_interruptible(&sfp->read_wait);
     }
 }
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/scsi/st.c linux-2.4.29-pre3/drivers/scsi/st.c
--- linux-2.4.28/drivers/scsi/st.c	2004-08-07 23:26:05.000000000 +0000
+++ linux-2.4.29-pre3/drivers/scsi/st.c	2004-12-22 16:07:06.388205400 +0000
@@ -1641,7 +1641,7 @@ static long read_tape(Scsi_Tape *STp, lo
 							if (STps->drv_block >= 0)
 								STps->drv_block += 1;
 							(STp->buffer)->buffer_bytes = 0;
-							return (-ENOMEM);
+							return (-EIO);
 						}
 						(STp->buffer)->buffer_bytes = bytes - transfer;
 					} else {
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/scsi/sym53c8xx_2/sym_glue.c linux-2.4.29-pre3/drivers/scsi/sym53c8xx_2/sym_glue.c
--- linux-2.4.28/drivers/scsi/sym53c8xx_2/sym_glue.c	2002-11-28 23:53:14.000000000 +0000
+++ linux-2.4.29-pre3/drivers/scsi/sym53c8xx_2/sym_glue.c	2004-12-22 16:07:57.871378768 +0000
@@ -1149,7 +1149,6 @@ prepare:
 	switch(to_do) {
 	default:
 	case SYM_EH_DO_IGNORE:
-		goto finish;
 		break;
 	case SYM_EH_DO_WAIT:
 #if LINUX_VERSION_CODE > LinuxVersionCode(2,3,0)
@@ -1193,7 +1192,6 @@ prepare:
 		to_do = SYM_EH_DO_IGNORE;
 	}
 
-finish:
 	ep->to_do = to_do;
 	/* Complete the command with locks held as required by the driver */
 	if (to_do == SYM_EH_DO_COMPLETE)
@@ -1469,7 +1467,8 @@ static void sym_exec_user_command (hcb_p
 					tp->tinfo.goal.offset  = 0;
 					break;
 				}
-				if (uc->data <= 9 && np->minsync_dt) {
+				if (uc->data <= 9 && np->minsync_dt &&
+				    np->scsi_mode == SMODE_LVD) {
 					if (uc->data < np->minsync_dt)
 						uc->data = np->minsync_dt;
 					tp->tinfo.goal.options = PPR_OPT_DT;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/scsi/sym53c8xx_2/sym_misc.c linux-2.4.29-pre3/drivers/scsi/sym53c8xx_2/sym_misc.c
--- linux-2.4.28/drivers/scsi/sym53c8xx_2/sym_misc.c	2001-11-09 23:22:54.000000000 +0000
+++ linux-2.4.29-pre3/drivers/scsi/sym53c8xx_2/sym_misc.c	2004-12-22 16:07:33.051152016 +0000
@@ -315,7 +315,7 @@ __sym_sniff_inquiry(hcb_p np, u_char tn,
 	 */
 	inq_byte56 = tp->inq_byte56;
 	if (inq_version >= 4 && inq_len > 56)
-		tp->inq_byte56 = inq_data[56];
+		inq_byte56 = inq_data[56];
 #if 0
 printf("XXXXXX [%d] inq_version=%x inq_byte7=%x inq_byte56=%x XXXXX\n",
 	inq_len, inq_version, inq_byte7, inq_byte56);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/sound/Config.in linux-2.4.29-pre3/drivers/sound/Config.in
--- linux-2.4.28/drivers/sound/Config.in	2003-11-28 18:26:20.000000000 +0000
+++ linux-2.4.29-pre3/drivers/sound/Config.in	2004-12-22 16:07:09.865676744 +0000
@@ -74,6 +74,8 @@ if [ "$CONFIG_DDB5477" = "y" ]; then
 fi
 if [ "$CONFIG_SOC_AU1X00" = "y" -o  "$CONFIG_SOC_AU1500" = "y" ]; then
     dep_tristate '  Au1x00 Sound' CONFIG_SOUND_AU1X00 $CONFIG_SOUND
+    dep_tristate '  Au1550 PSC Sound' CONFIG_SOUND_AU1550_PSC $CONFIG_SOUND
+    dep_tristate '  Au1550 I2S Sound' CONFIG_SOUND_AU1550_I2S $CONFIG_SOUND
 fi
 
 dep_tristate '  Trident 4DWave DX/NX, SiS 7018 or ALi 5451 PCI Audio Core' CONFIG_SOUND_TRIDENT $CONFIG_SOUND $CONFIG_PCI
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/sound/Makefile linux-2.4.29-pre3/drivers/sound/Makefile
--- linux-2.4.28/drivers/sound/Makefile	2003-11-28 18:26:20.000000000 +0000
+++ linux-2.4.29-pre3/drivers/sound/Makefile	2004-12-22 16:06:08.752967288 +0000
@@ -69,6 +69,8 @@ obj-$(CONFIG_SOUND_ES1370)	+= es1370.o
 obj-$(CONFIG_SOUND_ES1371)	+= es1371.o ac97_codec.o
 obj-$(CONFIG_SOUND_VRC5477)	+= nec_vrc5477.o ac97_codec.o
 obj-$(CONFIG_SOUND_AU1X00)      += au1000.o ac97_codec.o  
+obj-$(CONFIG_SOUND_AU1550_PSC)  += au1550_psc.o ac97_codec.o  
+obj-$(CONFIG_SOUND_AU1550_I2S)  += au1550_i2s.o
 obj-$(CONFIG_SOUND_ESSSOLO1)	+= esssolo1.o
 obj-$(CONFIG_SOUND_FUSION)	+= cs46xx.o ac97_codec.o
 obj-$(CONFIG_SOUND_MAESTRO)	+= maestro.o
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/sound/au1550_i2s.c linux-2.4.29-pre3/drivers/sound/au1550_i2s.c
--- linux-2.4.28/drivers/sound/au1550_i2s.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/drivers/sound/au1550_i2s.c	2004-12-22 16:07:03.573633280 +0000
@@ -0,0 +1,1937 @@
+/*
+ *      au1550_i2s.c  --  Sound driver for Alchemy Au1550 MIPS
+ *			Internet Edge Processor.
+ *
+ * Copyright 2004 Embedded Edge, LLC
+ *	dan@embeddededge.com
+ *
+ * So, I was stupid.....Although this is an I2S interface, it still uses
+ * the PSC for communication.  The existing au1550_psc.c should have been
+ * called au1550_ac97.c or something.  Not going to rename anything now.
+ *
+ * Mostly copied from the au1550_psc.c driver and some from the
+ * PowerMac dbdma driver.
+ * We assume the processor can do memory coherent DMA.
+ *
+ * The SMBus (I2C) is required for the control of the codec.  It
+ * appears at I2C address 0x36 (I2C binary 0011011).  The Pb1550
+ * uses the Wolfson WM8731 codec, which is controlled over the I2C.
+ * It's connected to a 12MHz clock, so we can only reliably support
+ * 96KHz, 48KHz, 32KHz, and 8KHz data rates.  The framework for variable
+ * rate audio is in place, but we currently force it to 48KHz.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/sound.h>
+#include <linux/slab.h>
+#include <linux/soundcard.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/pci.h>
+#include <linux/bitops.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
+#include <linux/wrapper.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/hardirq.h>
+#include <asm/au1000.h>
+#include <asm/pb1550.h>
+#include <asm/au1xxx_psc.h>
+#include <asm/au1xxx_dbdma.h>
+
+#undef OSS_DOCUMENTED_MIXER_SEMANTICS
+
+#define AU1550_MODULE_NAME "Au1550 i2s audio"
+#define PFX AU1550_MODULE_NAME
+
+/* Define this if you want to try running at the 44.1 KHz rate.
+ * It's just a little off, I think it's actually 44117 or something.
+ * I did this for debugging, since many programs, including this
+ * driver, will try to upsample from 44.1 to 48 KHz.
+ * Seems to work well, we'll just leave it this way.
+ */
+#define TRY_441KHz
+
+#ifdef TRY_441KHz
+#define SAMP_RATE	44100
+#else
+#define SAMP_RATE	48000
+#endif
+
+/* The number of DBDMA ring descriptors to allocate.  No sense making
+ * this too large....if you can't keep up with a few you aren't likely
+ * to be able to with lots of them, either.
+ */
+#define NUM_DBDMA_DESCRIPTORS 4
+
+#define err(format, arg...) printk(KERN_ERR PFX ": " format "\n" , ## arg)
+#define info(format, arg...) printk(KERN_INFO PFX ": " format "\n" , ## arg)
+
+/* Boot options
+ * 0 = no VRA, 1 = use VRA if codec supports it
+ * The framework is here, but we currently force no VRA.
+ */
+static int      vra = 0;
+MODULE_PARM(vra, "i");
+MODULE_PARM_DESC(vra, "if 1 use VRA if codec supports it");
+
+static struct au1550_state {
+	/* soundcore stuff */
+	int             dev_audio;
+
+	spinlock_t		lock;
+	struct semaphore	open_sem;
+	struct semaphore	sem;
+	mode_t			open_mode;
+	wait_queue_head_t	open_wait;
+	int			no_vra;
+	volatile psc_i2s_t	*psc_addr;
+
+	struct dmabuf {
+		u32		dmanr;
+		unsigned        sample_rate;
+		unsigned	src_factor;
+		unsigned        sample_size;
+		int             num_channels;
+		int		dma_bytes_per_sample;
+		int		user_bytes_per_sample;
+		int		cnt_factor;
+
+		void		*rawbuf;
+		unsigned        buforder;
+		unsigned	numfrag;
+		unsigned        fragshift;
+		void		*nextIn;
+		void		*nextOut;
+		int		count;
+		unsigned        total_bytes;
+		unsigned        error;
+		wait_queue_head_t wait;
+
+		/* redundant, but makes calculations easier */
+		unsigned	fragsize;
+		unsigned	dma_fragsize;
+		unsigned	dmasize;
+		unsigned	dma_qcount;
+
+		/* OSS stuff */
+		unsigned        mapped:1;
+		unsigned        ready:1;
+		unsigned        stopped:1;
+		unsigned        ossfragshift;
+		int             ossmaxfrags;
+		unsigned        subdivision;
+	} dma_dac, dma_adc;
+} au1550_state;
+
+static unsigned
+ld2(unsigned int x)
+{
+	unsigned        r = 0;
+
+	if (x >= 0x10000) {
+		x >>= 16;
+		r += 16;
+	}
+	if (x >= 0x100) {
+		x >>= 8;
+		r += 8;
+	}
+	if (x >= 0x10) {
+		x >>= 4;
+		r += 4;
+	}
+	if (x >= 4) {
+		x >>= 2;
+		r += 2;
+	}
+	if (x >= 2)
+		r++;
+	return r;
+}
+
+static void
+au1550_delay(int msec)
+{
+	unsigned long   tmo;
+	signed long     tmo2;
+
+	if (in_interrupt())
+		return;
+
+	tmo = jiffies + (msec * HZ) / 1000;
+	for (;;) {
+		tmo2 = tmo - jiffies;
+		if (tmo2 <= 0)
+			break;
+		schedule_timeout(tmo2);
+	}
+}
+
+/* Just a place holder.  The Wolfson codec is a write only device,
+ * so we would have to keep a local copy of the data.
+ */
+#if 0
+static u8
+rdcodec(u8 addr)
+{
+	return 0  /* data */;
+}
+#endif
+
+
+static void
+wrcodec(u8 ctlreg, u8 val)
+{
+	int	rcnt;
+	extern int pb1550_wm_codec_write(u8 addr, u8 reg, u8 val);
+
+	/* The codec is a write only device, with a 16-bit control/data
+	 * word.  Although it is written as two bytes on the I2C, the
+	 * format is actually 7 bits of register and 9 bits of data.
+	 * The ls bit of the first byte is the ms bit of the data.
+	 */
+	rcnt = 0;
+	while ((pb1550_wm_codec_write((0x36 >> 1), ctlreg, val) != 1) 
+							&& (rcnt < 50)) {
+		rcnt++;
+#if 0
+		printk("Codec write retry %02x %02x\n", ctlreg, val);
+#endif
+	}
+}
+
+void
+codec_init(void)
+{
+	wrcodec(0x1e, 0x00);	/* Reset */
+	au1550_delay(200);
+	wrcodec(0x0c, 0x00);	/* Power up everything */
+	au1550_delay(10);
+	wrcodec(0x12, 0x00);	/* Deactivate codec */
+	au1550_delay(10);
+	wrcodec(0x08, 0x10);	/* Select DAC outputs to line out */
+	au1550_delay(10);
+	wrcodec(0x0a, 0x00);	/* Disable output mute */
+	au1550_delay(10);
+	wrcodec(0x05, 0x70);	/* lower output volume on headphone */
+	au1550_delay(10);
+	wrcodec(0x0e, 0x02);	/* Set slave, 16-bit, I2S modes */
+	au1550_delay(10);
+	wrcodec(0x10, 0x01);	/* 12MHz (USB), 250fs */
+	au1550_delay(10);
+	wrcodec(0x12, 0x01);	/* Activate codec */
+	au1550_delay(10);
+}
+
+/* stop the ADC before calling */
+static void
+set_adc_rate(struct au1550_state *s, unsigned rate)
+{
+	struct dmabuf  *adc = &s->dma_adc;
+	struct dmabuf  *dac = &s->dma_dac;
+
+	if (s->no_vra) {
+		/* calc SRC factor
+		*/
+		adc->src_factor = (((SAMP_RATE*2) / rate) + 1) >> 1;
+		adc->sample_rate = SAMP_RATE / adc->src_factor;
+		return;
+	}
+
+	adc->src_factor = 1;
+
+
+#if 0
+	rate = rate > SAMP_RATE ? SAMP_RATE : rate;
+
+	wrcodec(0, 0);	/* I don't yet know what to write here if we vra */
+
+	adc->sample_rate = rate;
+	dac->sample_rate = rate;
+#endif
+}
+
+/* stop the DAC before calling */
+static void
+set_dac_rate(struct au1550_state *s, unsigned rate)
+{
+	struct dmabuf  *dac = &s->dma_dac;
+	struct dmabuf  *adc = &s->dma_adc;
+
+	if (s->no_vra) {
+		/* calc SRC factor
+		*/
+		dac->src_factor = (((SAMP_RATE*2) / rate) + 1) >> 1;
+		dac->sample_rate = SAMP_RATE / dac->src_factor;
+		return;
+	}
+
+	dac->src_factor = 1;
+
+#if 0
+	rate = rate > SAMP_RATE ? SAMP_RATE : rate;
+
+	wrcodec(0, 0);	/* I don't yet know what to write here if we vra */
+
+	adc->sample_rate = rate;
+	dac->sample_rate = rate;
+#endif
+}
+
+static void
+stop_dac(struct au1550_state *s)
+{
+	struct dmabuf  *db = &s->dma_dac;
+	unsigned long   flags;
+	uint	stat;
+	volatile psc_i2s_t *ip;
+
+	if (db->stopped)
+		return;
+
+	ip = s->psc_addr;
+	spin_lock_irqsave(&s->lock, flags);
+
+	ip->psc_i2spcr = PSC_I2SPCR_TP;
+	au_sync();
+
+	/* Wait for Transmit Busy to show disabled.
+	*/
+	do {
+		stat = ip->psc_i2sstat;
+		au_sync();
+	} while ((stat & PSC_I2SSTAT_TB) != 0);
+
+	au1xxx_dbdma_reset(db->dmanr);
+
+	db->stopped = 1;
+
+	spin_unlock_irqrestore(&s->lock, flags);
+}
+
+static void
+stop_adc(struct au1550_state *s)
+{
+	struct dmabuf  *db = &s->dma_adc;
+	unsigned long   flags;
+	uint	stat;
+	volatile psc_i2s_t *ip;
+
+	if (db->stopped)
+		return;
+
+	ip = s->psc_addr;
+	spin_lock_irqsave(&s->lock, flags);
+
+	ip->psc_i2spcr = PSC_I2SPCR_RP;
+	au_sync();
+
+	/* Wait for Receive Busy to show disabled.
+	*/
+	do {
+		stat = ip->psc_i2sstat;
+		au_sync();
+	} while ((stat & PSC_I2SSTAT_RB) != 0);
+
+	au1xxx_dbdma_reset(db->dmanr);
+
+	db->stopped = 1;
+
+	spin_unlock_irqrestore(&s->lock, flags);
+}
+
+
+static void
+set_xmit_slots(int num_channels)
+{
+	/* This is here just as a place holder.  The WM8731 only
+	 * supports two fixed channels.
+	 */
+}
+
+static void
+set_recv_slots(int num_channels)
+{
+	/* This is here just as a place holder.  The WM8731 only
+	 * supports two fixed channels.
+	 */
+}
+
+static void
+start_dac(struct au1550_state *s)
+{
+	struct dmabuf  *db = &s->dma_dac;
+	unsigned long   flags;
+	volatile psc_i2s_t *ip;
+
+	if (!db->stopped)
+		return;
+
+	spin_lock_irqsave(&s->lock, flags);
+
+	ip = s->psc_addr;
+	set_xmit_slots(db->num_channels);
+	ip->psc_i2spcr = PSC_I2SPCR_TC;
+	au_sync();
+	ip->psc_i2spcr = PSC_I2SPCR_TS;
+	au_sync();
+
+	au1xxx_dbdma_start(db->dmanr);
+
+	db->stopped = 0;
+
+	spin_unlock_irqrestore(&s->lock, flags);
+}
+
+static void
+start_adc(struct au1550_state *s)
+{
+	struct dmabuf  *db = &s->dma_adc;
+	int	i;
+	volatile psc_i2s_t *ip;
+
+	if (!db->stopped)
+		return;
+
+	/* Put two buffers on the ring to get things started.
+	*/
+	for (i=0; i<2; i++) {
+		au1xxx_dbdma_put_dest(db->dmanr, db->nextIn, db->dma_fragsize);
+
+		db->nextIn += db->dma_fragsize;
+		if (db->nextIn >= db->rawbuf + db->dmasize)
+			db->nextIn -= db->dmasize;
+	}
+
+	ip = s->psc_addr;
+	set_recv_slots(db->num_channels);
+	au1xxx_dbdma_start(db->dmanr);
+	ip->psc_i2spcr = PSC_I2SPCR_RC;
+	au_sync();
+	ip->psc_i2spcr = PSC_I2SPCR_RS;
+	au_sync();
+
+	db->stopped = 0;
+}
+
+static int
+prog_dmabuf(struct au1550_state *s, struct dmabuf *db)
+{
+	unsigned user_bytes_per_sec;
+	unsigned        bufs;
+	unsigned        rate = db->sample_rate;
+
+	if (!db->rawbuf) {
+		db->ready = db->mapped = 0;
+		db->buforder = 5;	/* 32 * PAGE_SIZE */
+		db->rawbuf = kmalloc((PAGE_SIZE << db->buforder), GFP_KERNEL);
+		if (!db->rawbuf)
+			return -ENOMEM;
+	}
+
+	db->cnt_factor = 1;
+	if (db->sample_size == 8)
+		db->cnt_factor *= 2;
+	if (db->num_channels == 1)
+		db->cnt_factor *= 2;
+	db->cnt_factor *= db->src_factor;
+
+	db->count = 0;
+	db->dma_qcount = 0;
+	db->nextIn = db->nextOut = db->rawbuf;
+
+	db->user_bytes_per_sample = (db->sample_size>>3) * db->num_channels;
+	db->dma_bytes_per_sample = 2 * ((db->num_channels == 1) ?
+					2 : db->num_channels);
+
+	user_bytes_per_sec = rate * db->user_bytes_per_sample;
+	bufs = PAGE_SIZE << db->buforder;
+	if (db->ossfragshift) {
+		if ((1000 << db->ossfragshift) < user_bytes_per_sec)
+			db->fragshift = ld2(user_bytes_per_sec/1000);
+		else
+			db->fragshift = db->ossfragshift;
+	} else {
+		db->fragshift = ld2(user_bytes_per_sec / 100 /
+				    (db->subdivision ? db->subdivision : 1));
+		if (db->fragshift < 3)
+			db->fragshift = 3;
+	}
+
+	db->fragsize = 1 << db->fragshift;
+	db->dma_fragsize = db->fragsize * db->cnt_factor;
+	db->numfrag = bufs / db->dma_fragsize;
+
+	while (db->numfrag < 4 && db->fragshift > 3) {
+		db->fragshift--;
+		db->fragsize = 1 << db->fragshift;
+		db->dma_fragsize = db->fragsize * db->cnt_factor;
+		db->numfrag = bufs / db->dma_fragsize;
+	}
+
+	if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
+		db->numfrag = db->ossmaxfrags;
+
+	db->dmasize = db->dma_fragsize * db->numfrag;
+	memset(db->rawbuf, 0, bufs);
+
+#ifdef AU1000_VERBOSE_DEBUG
+	dbg("rate=%d, samplesize=%d, channels=%d",
+	    rate, db->sample_size, db->num_channels);
+	dbg("fragsize=%d, cnt_factor=%d, dma_fragsize=%d",
+	    db->fragsize, db->cnt_factor, db->dma_fragsize);
+	dbg("numfrag=%d, dmasize=%d", db->numfrag, db->dmasize);
+#endif
+
+	db->ready = 1;
+	return 0;
+}
+
+static int
+prog_dmabuf_adc(struct au1550_state *s)
+{
+	stop_adc(s);
+	return prog_dmabuf(s, &s->dma_adc);
+
+}
+
+static int
+prog_dmabuf_dac(struct au1550_state *s)
+{
+	stop_dac(s);
+	return prog_dmabuf(s, &s->dma_dac);
+}
+
+
+/* hold spinlock for the following */
+static void
+dac_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct au1550_state *s = (struct au1550_state *) dev_id;
+	struct dmabuf  *db = &s->dma_dac;
+	u32	i2s_stat;
+	volatile psc_i2s_t *ip;
+
+	ip = s->psc_addr;
+	i2s_stat = ip->psc_i2sstat;
+#ifdef AU1000_VERBOSE_DEBUG
+	if (i2s_stat & (PSC_I2SSTAT_TF | PSC_I2SSTAT_TR | PSC_I2SSTAT_TF))
+		dbg("I2S status = 0x%08x", i2s_stat);
+#endif
+	db->dma_qcount--;
+
+	if (db->count >= db->fragsize) {
+		if (au1xxx_dbdma_put_source(db->dmanr, db->nextOut,
+							db->fragsize) == 0) {
+			err("qcount < 2 and no ring room!");
+		}
+		db->nextOut += db->fragsize;
+		if (db->nextOut >= db->rawbuf + db->dmasize)
+			db->nextOut -= db->dmasize;
+		db->count -= db->fragsize;
+		db->total_bytes += db->dma_fragsize;
+		db->dma_qcount++;
+	}
+
+	/* wake up anybody listening */
+	if (waitqueue_active(&db->wait))
+		wake_up(&db->wait);
+}
+
+
+static void
+adc_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct	au1550_state *s = (struct au1550_state *)dev_id;
+	struct	dmabuf  *dp = &s->dma_adc;
+	u32	obytes;
+	char	*obuf;
+
+	/* Pull the buffer from the dma queue.
+	*/
+	au1xxx_dbdma_get_dest(dp->dmanr, (void *)(&obuf), &obytes);
+
+	if ((dp->count + obytes) > dp->dmasize) {
+		/* Overrun. Stop ADC and log the error
+		*/
+		stop_adc(s);
+		dp->error++;
+		err("adc overrun");
+		return;
+	}
+
+	/* Put a new empty buffer on the destination DMA.
+	*/
+	au1xxx_dbdma_put_dest(dp->dmanr, dp->nextIn, dp->dma_fragsize);
+
+	dp->nextIn += dp->dma_fragsize;
+	if (dp->nextIn >= dp->rawbuf + dp->dmasize)
+		dp->nextIn -= dp->dmasize;
+
+	dp->count += obytes;
+	dp->total_bytes += obytes;
+
+	/* wake up anybody listening
+	*/
+	if (waitqueue_active(&dp->wait))
+		wake_up(&dp->wait);
+
+}
+
+static loff_t
+au1550_llseek(struct file *file, loff_t offset, int origin)
+{
+	return -ESPIPE;
+}
+
+
+#if 0
+static int
+au1550_open_mixdev(struct inode *inode, struct file *file)
+{
+	file->private_data = &au1550_state;
+	return 0;
+}
+
+static int
+au1550_release_mixdev(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+static int
+mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd,
+                        unsigned long arg)
+{
+	return codec->mixer_ioctl(codec, cmd, arg);
+}
+
+static int
+au1550_ioctl_mixdev(struct inode *inode, struct file *file,
+			       unsigned int cmd, unsigned long arg)
+{
+	struct au1550_state *s = (struct au1550_state *)file->private_data;
+	struct ac97_codec *codec = s->codec;
+
+	return mixdev_ioctl(codec, cmd, arg);
+}
+
+static /*const */ struct file_operations au1550_mixer_fops = {
+	owner:THIS_MODULE,
+	llseek:au1550_llseek,
+	ioctl:au1550_ioctl_mixdev,
+	open:au1550_open_mixdev,
+	release:au1550_release_mixdev,
+};
+#endif
+
+static int
+drain_dac(struct au1550_state *s, int nonblock)
+{
+	unsigned long   flags;
+	int             count, tmo;
+
+	if (s->dma_dac.mapped || !s->dma_dac.ready || s->dma_dac.stopped)
+		return 0;
+
+	for (;;) {
+		spin_lock_irqsave(&s->lock, flags);
+		count = s->dma_dac.count;
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count <= 0)
+			break;
+		if (signal_pending(current))
+			break;
+		if (nonblock)
+			return -EBUSY;
+		tmo = 1000 * count / (s->no_vra ?
+				      SAMP_RATE : s->dma_dac.sample_rate);
+		tmo /= s->dma_dac.dma_bytes_per_sample;
+		au1550_delay(tmo);
+	}
+	if (signal_pending(current))
+		return -ERESTARTSYS;
+	return 0;
+}
+
+static inline u8 S16_TO_U8(s16 ch)
+{
+	return (u8) (ch >> 8) + 0x80;
+}
+static inline s16 U8_TO_S16(u8 ch)
+{
+	return (s16) (ch - 0x80) << 8;
+}
+
+/*
+ * Translates user samples to dma buffer suitable for audio DAC data:
+ *     If mono, copy left channel to right channel in dma buffer.
+ *     If 8 bit samples, cvt to 16-bit before writing to dma buffer.
+ *     If interpolating (no VRA), duplicate every audio frame src_factor times.
+ */
+static int
+translate_from_user(struct dmabuf *db, char* dmabuf, char* userbuf,
+							       int dmacount)
+{
+	int             sample, i;
+	int             interp_bytes_per_sample;
+	int             num_samples;
+	int             mono = (db->num_channels == 1);
+	char            usersample[12];
+	s16             ch, dmasample[6];
+
+	if (db->sample_size == 16 && !mono && db->src_factor == 1) {
+		/* no translation necessary, just copy
+		*/
+		if (copy_from_user(dmabuf, userbuf, dmacount))
+			return -EFAULT;
+		return dmacount;
+	}
+
+	interp_bytes_per_sample = db->dma_bytes_per_sample * db->src_factor;
+	num_samples = dmacount / interp_bytes_per_sample;
+
+	for (sample = 0; sample < num_samples; sample++) {
+		if (copy_from_user(usersample, userbuf,
+				   db->user_bytes_per_sample)) {
+			return -EFAULT;
+		}
+
+		for (i = 0; i < db->num_channels; i++) {
+			if (db->sample_size == 8)
+				ch = U8_TO_S16(usersample[i]);
+			else
+				ch = *((s16 *) (&usersample[i * 2]));
+			dmasample[i] = ch;
+			if (mono)
+				dmasample[i + 1] = ch;	/* right channel */
+		}
+
+		/* duplicate every audio frame src_factor times
+		*/
+		for (i = 0; i < db->src_factor; i++)
+			memcpy(dmabuf, dmasample, db->dma_bytes_per_sample);
+
+		userbuf += db->user_bytes_per_sample;
+		dmabuf += interp_bytes_per_sample;
+	}
+
+	return num_samples * interp_bytes_per_sample;
+}
+
+/*
+ * Translates audio ADC samples to user buffer:
+ *     If mono, send only left channel to user buffer.
+ *     If 8 bit samples, cvt from 16 to 8 bit before writing to user buffer.
+ *     If decimating (no VRA), skip over src_factor audio frames.
+ */
+static int
+translate_to_user(struct dmabuf *db, char* userbuf, char* dmabuf,
+							     int dmacount)
+{
+	int             sample, i;
+	int             interp_bytes_per_sample;
+	int             num_samples;
+	int             mono = (db->num_channels == 1);
+	char            usersample[12];
+
+	if (db->sample_size == 16 && !mono && db->src_factor == 1) {
+		/* no translation necessary, just copy
+		*/
+		if (copy_to_user(userbuf, dmabuf, dmacount))
+			return -EFAULT;
+		return dmacount;
+	}
+
+	interp_bytes_per_sample = db->dma_bytes_per_sample * db->src_factor;
+	num_samples = dmacount / interp_bytes_per_sample;
+
+	for (sample = 0; sample < num_samples; sample++) {
+		for (i = 0; i < db->num_channels; i++) {
+			if (db->sample_size == 8)
+				usersample[i] =
+					S16_TO_U8(*((s16 *) (&dmabuf[i * 2])));
+			else
+				*((s16 *) (&usersample[i * 2])) =
+					*((s16 *) (&dmabuf[i * 2]));
+		}
+
+		if (copy_to_user(userbuf, usersample,
+				 db->user_bytes_per_sample)) {
+			return -EFAULT;
+		}
+
+		userbuf += db->user_bytes_per_sample;
+		dmabuf += interp_bytes_per_sample;
+	}
+
+	return num_samples * interp_bytes_per_sample;
+}
+
+/*
+ * Copy audio data to/from user buffer from/to dma buffer, taking care
+ * that we wrap when reading/writing the dma buffer. Returns actual byte
+ * count written to or read from the dma buffer.
+ */
+static int
+copy_dmabuf_user(struct dmabuf *db, char* userbuf, int count, int to_user)
+{
+	char           *bufptr = to_user ? db->nextOut : db->nextIn;
+	char           *bufend = db->rawbuf + db->dmasize;
+	int             cnt, ret;
+
+	if (bufptr + count > bufend) {
+		int             partial = (int) (bufend - bufptr);
+		if (to_user) {
+			if ((cnt = translate_to_user(db, userbuf,
+						     bufptr, partial)) < 0)
+				return cnt;
+			ret = cnt;
+			if ((cnt = translate_to_user(db, userbuf + partial,
+						     db->rawbuf,
+						     count - partial)) < 0)
+				return cnt;
+			ret += cnt;
+		} else {
+			if ((cnt = translate_from_user(db, bufptr, userbuf,
+						       partial)) < 0)
+				return cnt;
+			ret = cnt;
+			if ((cnt = translate_from_user(db, db->rawbuf,
+						       userbuf + partial,
+						       count - partial)) < 0)
+				return cnt;
+			ret += cnt;
+		}
+	} else {
+		if (to_user)
+			ret = translate_to_user(db, userbuf, bufptr, count);
+		else
+			ret = translate_from_user(db, bufptr, userbuf, count);
+	}
+
+	return ret;
+}
+
+
+static ssize_t
+au1550_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+{
+	struct au1550_state *s = (struct au1550_state *)file->private_data;
+	struct dmabuf  *db = &s->dma_adc;
+	DECLARE_WAITQUEUE(wait, current);
+	ssize_t         ret;
+	unsigned long   flags;
+	int             cnt, usercnt, avail;
+
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+	if (db->mapped)
+		return -ENXIO;
+	if (!access_ok(VERIFY_WRITE, buffer, count))
+		return -EFAULT;
+	ret = 0;
+
+	count *= db->cnt_factor;
+
+	down(&s->sem);
+	add_wait_queue(&db->wait, &wait);
+
+	while (count > 0) {
+		/* wait for samples in ADC dma buffer
+		*/
+		do {
+			if (db->stopped)
+				start_adc(s);
+			spin_lock_irqsave(&s->lock, flags);
+			avail = db->count;
+			if (avail <= 0)
+				__set_current_state(TASK_INTERRUPTIBLE);
+			spin_unlock_irqrestore(&s->lock, flags);
+			if (avail <= 0) {
+				if (file->f_flags & O_NONBLOCK) {
+					if (!ret)
+						ret = -EAGAIN;
+					goto out;
+				}
+				up(&s->sem);
+				schedule();
+				if (signal_pending(current)) {
+					if (!ret)
+						ret = -ERESTARTSYS;
+					goto out2;
+				}
+				down(&s->sem);
+			}
+		} while (avail <= 0);
+
+		/* copy from nextOut to user
+		*/
+		if ((cnt = copy_dmabuf_user(db, buffer,
+					    count > avail ?
+					    avail : count, 1)) < 0) {
+			if (!ret)
+				ret = -EFAULT;
+			goto out;
+		}
+
+		spin_lock_irqsave(&s->lock, flags);
+		db->count -= cnt;
+		db->nextOut += cnt;
+		if (db->nextOut >= db->rawbuf + db->dmasize)
+			db->nextOut -= db->dmasize;
+		spin_unlock_irqrestore(&s->lock, flags);
+
+		count -= cnt;
+		usercnt = cnt / db->cnt_factor;
+		buffer += usercnt;
+		ret += usercnt;
+	}			/* while (count > 0) */
+
+out:
+	up(&s->sem);
+out2:
+	remove_wait_queue(&db->wait, &wait);
+	set_current_state(TASK_RUNNING);
+	return ret;
+}
+
+static ssize_t
+au1550_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
+{
+	struct au1550_state *s = (struct au1550_state *)file->private_data;
+	struct dmabuf  *db = &s->dma_dac;
+	DECLARE_WAITQUEUE(wait, current);
+	ssize_t         ret = 0;
+	unsigned long   flags;
+	int             cnt, usercnt, avail;
+
+#ifdef AU1000_VERBOSE_DEBUG
+	dbg("write: count=%d", count);
+#endif
+
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+	if (db->mapped)
+		return -ENXIO;
+	if (!access_ok(VERIFY_READ, buffer, count))
+		return -EFAULT;
+
+	count *= db->cnt_factor;
+
+	down(&s->sem);	
+	add_wait_queue(&db->wait, &wait);
+
+	while (count > 0) {
+		/* wait for space in playback buffer
+		*/
+		do {
+			spin_lock_irqsave(&s->lock, flags);
+			avail = (int) db->dmasize - db->count;
+			if (avail <= 0)
+				__set_current_state(TASK_INTERRUPTIBLE);
+			spin_unlock_irqrestore(&s->lock, flags);
+			if (avail <= 0) {
+				if (file->f_flags & O_NONBLOCK) {
+					if (!ret)
+						ret = -EAGAIN;
+					goto out;
+				}
+				up(&s->sem);
+				schedule();
+				if (signal_pending(current)) {
+					if (!ret)
+						ret = -ERESTARTSYS;
+					goto out2;
+				}
+				down(&s->sem);
+			}
+		} while (avail <= 0);
+
+		/* copy from user to nextIn
+		*/
+		if ((cnt = copy_dmabuf_user(db, (char *) buffer,
+					    count > avail ?
+					    avail : count, 0)) < 0) {
+			if (!ret)
+				ret = -EFAULT;
+			goto out;
+		}
+
+		spin_lock_irqsave(&s->lock, flags);
+		db->count += cnt;
+		db->nextIn += cnt;
+		if (db->nextIn >= db->rawbuf + db->dmasize)
+			db->nextIn -= db->dmasize;
+
+		/* If the data is available, we want to keep two buffers
+		 * on the dma queue.  If the queue count reaches zero,
+		 * we know the dma has stopped.
+		 */
+		while ((db->dma_qcount < 2) && (db->count >= db->fragsize)) {
+			if (au1xxx_dbdma_put_source(db->dmanr, db->nextOut,
+							db->fragsize) == 0) {
+				err("qcount < 2 and no ring room!");
+			}
+			db->nextOut += db->fragsize;
+			if (db->nextOut >= db->rawbuf + db->dmasize)
+				db->nextOut -= db->dmasize;
+			db->count -= db->fragsize;
+			db->total_bytes += db->dma_fragsize;
+			if (db->dma_qcount == 0)
+				start_dac(s);
+			db->dma_qcount++;
+		}
+		spin_unlock_irqrestore(&s->lock, flags);
+
+		count -= cnt;
+		usercnt = cnt / db->cnt_factor;
+		buffer += usercnt;
+		ret += usercnt;
+	}			/* while (count > 0) */
+
+out:
+	up(&s->sem);
+out2:
+	remove_wait_queue(&db->wait, &wait);
+	set_current_state(TASK_RUNNING);
+	return ret;
+}
+
+
+/* No kernel lock - we have our own spinlock */
+static unsigned int
+au1550_poll(struct file *file, struct poll_table_struct *wait)
+{
+	struct au1550_state *s = (struct au1550_state *)file->private_data;
+	unsigned long   flags;
+	unsigned int    mask = 0;
+
+	if (file->f_mode & FMODE_WRITE) {
+		if (!s->dma_dac.ready)
+			return 0;
+		poll_wait(file, &s->dma_dac.wait, wait);
+	}
+	if (file->f_mode & FMODE_READ) {
+		if (!s->dma_adc.ready)
+			return 0;
+		poll_wait(file, &s->dma_adc.wait, wait);
+	}
+
+	spin_lock_irqsave(&s->lock, flags);
+	
+	if (file->f_mode & FMODE_READ) {
+		if (s->dma_adc.count >= (signed)s->dma_adc.dma_fragsize)
+			mask |= POLLIN | POLLRDNORM;
+	}
+	if (file->f_mode & FMODE_WRITE) {
+		if (s->dma_dac.mapped) {
+			if (s->dma_dac.count >=
+			    (signed)s->dma_dac.dma_fragsize) 
+				mask |= POLLOUT | POLLWRNORM;
+		} else {
+			if ((signed) s->dma_dac.dmasize >=
+			    s->dma_dac.count + (signed)s->dma_dac.dma_fragsize)
+				mask |= POLLOUT | POLLWRNORM;
+		}
+	}
+	spin_unlock_irqrestore(&s->lock, flags);
+	return mask;
+}
+
+static int
+au1550_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	struct au1550_state *s = (struct au1550_state *)file->private_data;
+	struct dmabuf  *db;
+	unsigned long   size;
+	int ret = 0;
+
+	lock_kernel();
+	down(&s->sem);
+	if (vma->vm_flags & VM_WRITE)
+		db = &s->dma_dac;
+	else if (vma->vm_flags & VM_READ)
+		db = &s->dma_adc;
+	else {
+		ret = -EINVAL;
+		goto out;
+	}
+	if (vma->vm_pgoff != 0) {
+		ret = -EINVAL;
+		goto out;
+	}
+	size = vma->vm_end - vma->vm_start;
+	if (size > (PAGE_SIZE << db->buforder)) {
+		ret = -EINVAL;
+		goto out;
+	}
+	if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf),
+			     size, vma->vm_page_prot)) {
+		ret = -EAGAIN;
+		goto out;
+	}
+	vma->vm_flags &= ~VM_IO;
+	db->mapped = 1;
+out:
+	up(&s->sem);
+	unlock_kernel();
+	return ret;
+}
+
+
+#ifdef AU1000_VERBOSE_DEBUG
+static struct ioctl_str_t {
+	unsigned int    cmd;
+	const char     *str;
+} ioctl_str[] = {
+	{SNDCTL_DSP_RESET, "SNDCTL_DSP_RESET"},
+	{SNDCTL_DSP_SYNC, "SNDCTL_DSP_SYNC"},
+	{SNDCTL_DSP_SPEED, "SNDCTL_DSP_SPEED"},
+	{SNDCTL_DSP_STEREO, "SNDCTL_DSP_STEREO"},
+	{SNDCTL_DSP_GETBLKSIZE, "SNDCTL_DSP_GETBLKSIZE"},
+	{SNDCTL_DSP_SAMPLESIZE, "SNDCTL_DSP_SAMPLESIZE"},
+	{SNDCTL_DSP_CHANNELS, "SNDCTL_DSP_CHANNELS"},
+	{SOUND_PCM_WRITE_CHANNELS, "SOUND_PCM_WRITE_CHANNELS"},
+	{SOUND_PCM_WRITE_FILTER, "SOUND_PCM_WRITE_FILTER"},
+	{SNDCTL_DSP_POST, "SNDCTL_DSP_POST"},
+	{SNDCTL_DSP_SUBDIVIDE, "SNDCTL_DSP_SUBDIVIDE"},
+	{SNDCTL_DSP_SETFRAGMENT, "SNDCTL_DSP_SETFRAGMENT"},
+	{SNDCTL_DSP_GETFMTS, "SNDCTL_DSP_GETFMTS"},
+	{SNDCTL_DSP_SETFMT, "SNDCTL_DSP_SETFMT"},
+	{SNDCTL_DSP_GETOSPACE, "SNDCTL_DSP_GETOSPACE"},
+	{SNDCTL_DSP_GETISPACE, "SNDCTL_DSP_GETISPACE"},
+	{SNDCTL_DSP_NONBLOCK, "SNDCTL_DSP_NONBLOCK"},
+	{SNDCTL_DSP_GETCAPS, "SNDCTL_DSP_GETCAPS"},
+	{SNDCTL_DSP_GETTRIGGER, "SNDCTL_DSP_GETTRIGGER"},
+	{SNDCTL_DSP_SETTRIGGER, "SNDCTL_DSP_SETTRIGGER"},
+	{SNDCTL_DSP_GETIPTR, "SNDCTL_DSP_GETIPTR"},
+	{SNDCTL_DSP_GETOPTR, "SNDCTL_DSP_GETOPTR"},
+	{SNDCTL_DSP_MAPINBUF, "SNDCTL_DSP_MAPINBUF"},
+	{SNDCTL_DSP_MAPOUTBUF, "SNDCTL_DSP_MAPOUTBUF"},
+	{SNDCTL_DSP_SETSYNCRO, "SNDCTL_DSP_SETSYNCRO"},
+	{SNDCTL_DSP_SETDUPLEX, "SNDCTL_DSP_SETDUPLEX"},
+	{SNDCTL_DSP_GETODELAY, "SNDCTL_DSP_GETODELAY"},
+	{SNDCTL_DSP_GETCHANNELMASK, "SNDCTL_DSP_GETCHANNELMASK"},
+	{SNDCTL_DSP_BIND_CHANNEL, "SNDCTL_DSP_BIND_CHANNEL"},
+	{OSS_GETVERSION, "OSS_GETVERSION"},
+	{SOUND_PCM_READ_RATE, "SOUND_PCM_READ_RATE"},
+	{SOUND_PCM_READ_CHANNELS, "SOUND_PCM_READ_CHANNELS"},
+	{SOUND_PCM_READ_BITS, "SOUND_PCM_READ_BITS"},
+	{SOUND_PCM_READ_FILTER, "SOUND_PCM_READ_FILTER"}
+};
+#endif
+
+static int
+dma_count_done(struct dmabuf *db)
+{
+	if (db->stopped)
+		return 0;
+
+	return db->dma_fragsize - au1xxx_get_dma_residue(db->dmanr);
+}
+
+
+static int
+au1550_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+							unsigned long arg)
+{
+	struct au1550_state *s = (struct au1550_state *)file->private_data;
+	unsigned long   flags;
+	audio_buf_info  abinfo;
+	count_info      cinfo;
+	int             count;
+	int             val, mapped, ret, diff;
+
+	mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
+		((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
+
+#ifdef AU1000_VERBOSE_DEBUG
+	for (count=0; count<sizeof(ioctl_str)/sizeof(ioctl_str[0]); count++) {
+		if (ioctl_str[count].cmd == cmd)
+			break;
+	}
+	if (count < sizeof(ioctl_str) / sizeof(ioctl_str[0]))
+		dbg("ioctl %s, arg=0x%lx", ioctl_str[count].str, arg);
+	else
+		dbg("ioctl 0x%x unknown, arg=0x%lx", cmd, arg);
+#endif
+
+	switch (cmd) {
+	case OSS_GETVERSION:
+		return put_user(SOUND_VERSION, (int *) arg);
+
+	case SNDCTL_DSP_SYNC:
+		if (file->f_mode & FMODE_WRITE)
+			return drain_dac(s, file->f_flags & O_NONBLOCK);
+		return 0;
+
+	case SNDCTL_DSP_SETDUPLEX:
+		return 0;
+
+	case SNDCTL_DSP_GETCAPS:
+		return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
+				DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
+
+	case SNDCTL_DSP_RESET:
+		if (file->f_mode & FMODE_WRITE) {
+			stop_dac(s);
+			synchronize_irq();
+			s->dma_dac.count = s->dma_dac.total_bytes = 0;
+			s->dma_dac.nextIn = s->dma_dac.nextOut =
+				s->dma_dac.rawbuf;
+		}
+		if (file->f_mode & FMODE_READ) {
+			stop_adc(s);
+			synchronize_irq();
+			s->dma_adc.count = s->dma_adc.total_bytes = 0;
+			s->dma_adc.nextIn = s->dma_adc.nextOut =
+				s->dma_adc.rawbuf;
+		}
+		return 0;
+
+	case SNDCTL_DSP_SPEED:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (val >= 0) {
+			if (file->f_mode & FMODE_READ) {
+				stop_adc(s);
+				set_adc_rate(s, val);
+			}
+			if (file->f_mode & FMODE_WRITE) {
+				stop_dac(s);
+				set_dac_rate(s, val);
+			}
+			if (s->open_mode & FMODE_READ)
+				if ((ret = prog_dmabuf_adc(s)))
+					return ret;
+			if (s->open_mode & FMODE_WRITE)
+				if ((ret = prog_dmabuf_dac(s)))
+					return ret;
+		}
+		return put_user((file->f_mode & FMODE_READ) ?
+				s->dma_adc.sample_rate :
+				s->dma_dac.sample_rate,
+				(int *)arg);
+
+	case SNDCTL_DSP_STEREO:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (file->f_mode & FMODE_READ) {
+			stop_adc(s);
+			s->dma_adc.num_channels = val ? 2 : 1;
+			if ((ret = prog_dmabuf_adc(s)))
+				return ret;
+		}
+		if (file->f_mode & FMODE_WRITE) {
+			stop_dac(s);
+			s->dma_dac.num_channels = val ? 2 : 1;
+			if ((ret = prog_dmabuf_dac(s)))
+				return ret;
+		}
+		return 0;
+
+	case SNDCTL_DSP_CHANNELS:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (val != 0) {
+			if (file->f_mode & FMODE_READ) {
+				if (val < 0 || val > 2)
+					return -EINVAL;
+				stop_adc(s);
+				s->dma_adc.num_channels = val;
+				if ((ret = prog_dmabuf_adc(s)))
+					return ret;
+			}
+			if (file->f_mode & FMODE_WRITE) {
+				switch (val) {
+				case 1:
+				case 2:
+					break;
+				default:
+					return -EINVAL;
+				}
+
+				stop_dac(s);
+				s->dma_dac.num_channels = val;
+				if ((ret = prog_dmabuf_dac(s)))
+					return ret;
+			}
+		}
+		return put_user(val, (int *) arg);
+
+	case SNDCTL_DSP_GETFMTS:	/* Returns a mask */
+		return put_user(AFMT_S16_LE | AFMT_U8, (int *) arg);
+
+	case SNDCTL_DSP_SETFMT:	/* Selects ONE fmt */
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (val != AFMT_QUERY) {
+			if (file->f_mode & FMODE_READ) {
+				stop_adc(s);
+				if (val == AFMT_S16_LE)
+					s->dma_adc.sample_size = 16;
+				else {
+					val = AFMT_U8;
+					s->dma_adc.sample_size = 8;
+				}
+				if ((ret = prog_dmabuf_adc(s)))
+					return ret;
+			}
+			if (file->f_mode & FMODE_WRITE) {
+				stop_dac(s);
+				if (val == AFMT_S16_LE)
+					s->dma_dac.sample_size = 16;
+				else {
+					val = AFMT_U8;
+					s->dma_dac.sample_size = 8;
+				}
+				if ((ret = prog_dmabuf_dac(s)))
+					return ret;
+			}
+		} else {
+			if (file->f_mode & FMODE_READ)
+				val = (s->dma_adc.sample_size == 16) ?
+					AFMT_S16_LE : AFMT_U8;
+			else
+				val = (s->dma_dac.sample_size == 16) ?
+					AFMT_S16_LE : AFMT_U8;
+		}
+		return put_user(val, (int *) arg);
+
+	case SNDCTL_DSP_POST:
+		return 0;
+
+	case SNDCTL_DSP_GETTRIGGER:
+		val = 0;
+		spin_lock_irqsave(&s->lock, flags);
+		if (file->f_mode & FMODE_READ && !s->dma_adc.stopped)
+			val |= PCM_ENABLE_INPUT;
+		if (file->f_mode & FMODE_WRITE && !s->dma_dac.stopped)
+			val |= PCM_ENABLE_OUTPUT;
+		spin_unlock_irqrestore(&s->lock, flags);
+		return put_user(val, (int *) arg);
+
+	case SNDCTL_DSP_SETTRIGGER:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (file->f_mode & FMODE_READ) {
+			if (val & PCM_ENABLE_INPUT)
+				start_adc(s);
+			else
+				stop_adc(s);
+		}
+		if (file->f_mode & FMODE_WRITE) {
+			if (val & PCM_ENABLE_OUTPUT)
+				start_dac(s);
+			else
+				stop_dac(s);
+		}
+		return 0;
+
+	case SNDCTL_DSP_GETOSPACE:
+		if (!(file->f_mode & FMODE_WRITE))
+			return -EINVAL;
+		abinfo.fragsize = s->dma_dac.fragsize;
+		spin_lock_irqsave(&s->lock, flags);
+		count = s->dma_dac.count;
+		count -= dma_count_done(&s->dma_dac);
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count < 0)
+			count = 0;
+		abinfo.bytes = (s->dma_dac.dmasize - count) /
+			s->dma_dac.cnt_factor;
+		abinfo.fragstotal = s->dma_dac.numfrag;
+		abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
+#ifdef AU1000_VERBOSE_DEBUG
+		dbg("bytes=%d, fragments=%d", abinfo.bytes, abinfo.fragments);
+#endif
+		return copy_to_user((void *) arg, &abinfo,
+				    sizeof(abinfo)) ? -EFAULT : 0;
+
+	case SNDCTL_DSP_GETISPACE:
+		if (!(file->f_mode & FMODE_READ))
+			return -EINVAL;
+		abinfo.fragsize = s->dma_adc.fragsize;
+		spin_lock_irqsave(&s->lock, flags);
+		count = s->dma_adc.count;
+		count += dma_count_done(&s->dma_adc);
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count < 0)
+			count = 0;
+		abinfo.bytes = count / s->dma_adc.cnt_factor;
+		abinfo.fragstotal = s->dma_adc.numfrag;
+		abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
+		return copy_to_user((void *) arg, &abinfo,
+				    sizeof(abinfo)) ? -EFAULT : 0;
+
+	case SNDCTL_DSP_NONBLOCK:
+		file->f_flags |= O_NONBLOCK;
+		return 0;
+
+	case SNDCTL_DSP_GETODELAY:
+		if (!(file->f_mode & FMODE_WRITE))
+			return -EINVAL;
+		spin_lock_irqsave(&s->lock, flags);
+		count = s->dma_dac.count;
+		count -= dma_count_done(&s->dma_dac);
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count < 0)
+			count = 0;
+		count /= s->dma_dac.cnt_factor;
+		return put_user(count, (int *) arg);
+
+	case SNDCTL_DSP_GETIPTR:
+		if (!(file->f_mode & FMODE_READ))
+			return -EINVAL;
+		spin_lock_irqsave(&s->lock, flags);
+		cinfo.bytes = s->dma_adc.total_bytes;
+		count = s->dma_adc.count;
+		if (!s->dma_adc.stopped) {
+			diff = dma_count_done(&s->dma_adc);
+			count += diff;
+			cinfo.bytes += diff;
+			cinfo.ptr =  virt_to_phys(s->dma_adc.nextIn) + diff -
+				virt_to_phys(s->dma_adc.rawbuf);
+		} else
+			cinfo.ptr = virt_to_phys(s->dma_adc.nextIn) -
+				virt_to_phys(s->dma_adc.rawbuf);
+		if (s->dma_adc.mapped)
+			s->dma_adc.count &= (s->dma_adc.dma_fragsize-1);
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count < 0)
+			count = 0;
+		cinfo.blocks = count >> s->dma_adc.fragshift;
+		return copy_to_user((void *) arg, &cinfo, sizeof(cinfo));
+
+	case SNDCTL_DSP_GETOPTR:
+		if (!(file->f_mode & FMODE_READ))
+			return -EINVAL;
+		spin_lock_irqsave(&s->lock, flags);
+		cinfo.bytes = s->dma_dac.total_bytes;
+		count = s->dma_dac.count;
+		if (!s->dma_dac.stopped) {
+			diff = dma_count_done(&s->dma_dac);
+			count -= diff;
+			cinfo.bytes += diff;
+			cinfo.ptr = virt_to_phys(s->dma_dac.nextOut) + diff -
+				virt_to_phys(s->dma_dac.rawbuf);
+		} else
+			cinfo.ptr = virt_to_phys(s->dma_dac.nextOut) -
+				virt_to_phys(s->dma_dac.rawbuf);
+		if (s->dma_dac.mapped)
+			s->dma_dac.count &= (s->dma_dac.dma_fragsize-1);
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count < 0)
+			count = 0;
+		cinfo.blocks = count >> s->dma_dac.fragshift;
+		return copy_to_user((void *) arg, &cinfo, sizeof(cinfo));
+
+	case SNDCTL_DSP_GETBLKSIZE:
+		if (file->f_mode & FMODE_WRITE)
+			return put_user(s->dma_dac.fragsize, (int *) arg);
+		else
+			return put_user(s->dma_adc.fragsize, (int *) arg);
+
+	case SNDCTL_DSP_SETFRAGMENT:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (file->f_mode & FMODE_READ) {
+			stop_adc(s);
+			s->dma_adc.ossfragshift = val & 0xffff;
+			s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
+			if (s->dma_adc.ossfragshift < 4)
+				s->dma_adc.ossfragshift = 4;
+			if (s->dma_adc.ossfragshift > 15)
+				s->dma_adc.ossfragshift = 15;
+			if (s->dma_adc.ossmaxfrags < 4)
+				s->dma_adc.ossmaxfrags = 4;
+			if ((ret = prog_dmabuf_adc(s)))
+				return ret;
+		}
+		if (file->f_mode & FMODE_WRITE) {
+			stop_dac(s);
+			s->dma_dac.ossfragshift = val & 0xffff;
+			s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
+			if (s->dma_dac.ossfragshift < 4)
+				s->dma_dac.ossfragshift = 4;
+			if (s->dma_dac.ossfragshift > 15)
+				s->dma_dac.ossfragshift = 15;
+			if (s->dma_dac.ossmaxfrags < 4)
+				s->dma_dac.ossmaxfrags = 4;
+			if ((ret = prog_dmabuf_dac(s)))
+				return ret;
+		}
+		return 0;
+
+	case SNDCTL_DSP_SUBDIVIDE:
+		if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
+		    (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
+			return -EINVAL;
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (val != 1 && val != 2 && val != 4)
+			return -EINVAL;
+		if (file->f_mode & FMODE_READ) {
+			stop_adc(s);
+			s->dma_adc.subdivision = val;
+			if ((ret = prog_dmabuf_adc(s)))
+				return ret;
+		}
+		if (file->f_mode & FMODE_WRITE) {
+			stop_dac(s);
+			s->dma_dac.subdivision = val;
+			if ((ret = prog_dmabuf_dac(s)))
+				return ret;
+		}
+		return 0;
+
+	case SOUND_PCM_READ_RATE:
+		return put_user((file->f_mode & FMODE_READ) ?
+				s->dma_adc.sample_rate :
+				s->dma_dac.sample_rate,
+				(int *)arg);
+
+	case SOUND_PCM_READ_CHANNELS:
+		if (file->f_mode & FMODE_READ)
+			return put_user(s->dma_adc.num_channels, (int *)arg);
+		else
+			return put_user(s->dma_dac.num_channels, (int *)arg);
+
+	case SOUND_PCM_READ_BITS:
+		if (file->f_mode & FMODE_READ)
+			return put_user(s->dma_adc.sample_size, (int *)arg);
+		else
+			return put_user(s->dma_dac.sample_size, (int *)arg);
+
+	case SOUND_PCM_WRITE_FILTER:
+	case SNDCTL_DSP_SETSYNCRO:
+	case SOUND_PCM_READ_FILTER:
+		return -EINVAL;
+	}
+
+#if 0
+	return mixdev_ioctl(s->codec, cmd, arg);
+#else
+	return 0;
+#endif
+}
+
+
+static int
+au1550_open(struct inode *inode, struct file *file)
+{
+	int             minor = MINOR(inode->i_rdev);
+	DECLARE_WAITQUEUE(wait, current);
+	struct au1550_state *s = &au1550_state;
+	int             ret;
+
+#ifdef AU1000_VERBOSE_DEBUG
+	if (file->f_flags & O_NONBLOCK)
+		dbg(__FUNCTION__ ": non-blocking");
+	else
+		dbg(__FUNCTION__ ": blocking");
+#endif
+	
+	file->private_data = s;
+	/* wait for device to become free */
+	down(&s->open_sem);
+	while (s->open_mode & file->f_mode) {
+		if (file->f_flags & O_NONBLOCK) {
+			up(&s->open_sem);
+			return -EBUSY;
+		}
+		add_wait_queue(&s->open_wait, &wait);
+		__set_current_state(TASK_INTERRUPTIBLE);
+		up(&s->open_sem);
+		schedule();
+		remove_wait_queue(&s->open_wait, &wait);
+		set_current_state(TASK_RUNNING);
+		if (signal_pending(current))
+			return -ERESTARTSYS;
+		down(&s->open_sem);
+	}
+
+	stop_dac(s);
+	stop_adc(s);
+
+	if (file->f_mode & FMODE_READ) {
+		s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags =
+			s->dma_adc.subdivision = s->dma_adc.total_bytes = 0;
+		s->dma_adc.num_channels = 1;
+		s->dma_adc.sample_size = 8;
+		set_adc_rate(s, 8000);
+		if ((minor & 0xf) == SND_DEV_DSP16)
+			s->dma_adc.sample_size = 16;
+	}
+
+	if (file->f_mode & FMODE_WRITE) {
+		s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags =
+			s->dma_dac.subdivision = s->dma_dac.total_bytes = 0;
+		s->dma_dac.num_channels = 1;
+		s->dma_dac.sample_size = 8;
+		set_dac_rate(s, 8000);
+		if ((minor & 0xf) == SND_DEV_DSP16)
+			s->dma_dac.sample_size = 16;
+	}
+
+	if (file->f_mode & FMODE_READ) {
+		if ((ret = prog_dmabuf_adc(s)))
+			return ret;
+	}
+	if (file->f_mode & FMODE_WRITE) {
+		if ((ret = prog_dmabuf_dac(s)))
+			return ret;
+	}
+
+	s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
+	up(&s->open_sem);
+	init_MUTEX(&s->sem);
+	return 0;
+}
+
+static int
+au1550_release(struct inode *inode, struct file *file)
+{
+	struct au1550_state *s = (struct au1550_state *)file->private_data;
+
+	lock_kernel();
+	
+	if (file->f_mode & FMODE_WRITE) {
+		unlock_kernel();
+		drain_dac(s, file->f_flags & O_NONBLOCK);
+		lock_kernel();
+	}
+
+	down(&s->open_sem);
+	if (file->f_mode & FMODE_WRITE) {
+		stop_dac(s);
+		kfree(s->dma_dac.rawbuf);
+		s->dma_dac.rawbuf = NULL;
+	}
+	if (file->f_mode & FMODE_READ) {
+		stop_adc(s);
+		kfree(s->dma_adc.rawbuf);
+		s->dma_adc.rawbuf = NULL;
+	}
+	s->open_mode &= ((~file->f_mode) & (FMODE_READ|FMODE_WRITE));
+	up(&s->open_sem);
+	wake_up(&s->open_wait);
+	unlock_kernel();
+	return 0;
+}
+
+static /*const */ struct file_operations au1550_audio_fops = {
+	owner:		THIS_MODULE,
+	llseek:		au1550_llseek,
+	read:		au1550_read,
+	write:		au1550_write,
+	poll:		au1550_poll,
+	ioctl:		au1550_ioctl,
+	mmap:		au1550_mmap,
+	open:		au1550_open,
+	release:	au1550_release,
+};
+
+MODULE_AUTHOR("Advanced Micro Devices (AMD), dan@embeddededge.com");
+MODULE_DESCRIPTION("Au1550 Audio Driver");
+
+/* Set up an internal clock for the PSC3.  This will then get
+ * driven out of the Au1550 as the master.
+ */
+static void
+intclk_setup(void)
+{
+	uint	clk, rate, stat;
+
+	/* Wire up Freq4 as a clock for the PSC3.
+	 * We know SMBus uses Freq3.
+	 * By making changes to this rate, plus the word strobe
+	 * size, we can make fine adjustments to the actual data rate.
+	 */
+	rate = get_au1x00_speed();
+#ifdef TRY_441KHz
+	rate /= (11 * 1000000);
+#else
+	rate /= (12 * 1000000);
+#endif
+
+	/* The FRDIV in the frequency control is (FRDIV + 1) * 2
+	*/
+	rate /=2;
+	rate--;
+	clk = au_readl(SYS_FREQCTRL1);
+	au_sync();
+	clk &= ~(SYS_FC_FRDIV4_MASK | SYS_FC_FS4);;
+	clk |= (rate << SYS_FC_FRDIV4_BIT);
+	clk |= SYS_FC_FE4;
+	au_writel(clk, SYS_FREQCTRL1);
+	au_sync();
+
+	/* Set up the clock source routing to get Freq4 to PSC3_intclk.
+	*/
+	clk = au_readl(SYS_CLKSRC);
+	au_sync();
+	clk &= ~0x01f00000;
+	clk |= (6 << 22);
+	au_writel(clk, SYS_CLKSRC);
+	au_sync();
+}
+
+static int __devinit
+au1550_probe(void)
+{
+	struct au1550_state *s = &au1550_state;
+	int             val;
+	volatile psc_i2s_t *ip;
+#ifdef AU1550_DEBUG
+	char            proc_str[80];
+#endif
+
+	memset(s, 0, sizeof(struct au1550_state));
+
+	init_waitqueue_head(&s->dma_adc.wait);
+	init_waitqueue_head(&s->dma_dac.wait);
+	init_waitqueue_head(&s->open_wait);
+	init_MUTEX(&s->open_sem);
+	spin_lock_init(&s->lock);
+
+
+	s->psc_addr = (volatile psc_i2s_t *)I2S_PSC_BASE;
+	ip = s->psc_addr;
+
+	if (!request_region(PHYSADDR(ip),
+			    0x30, AU1550_MODULE_NAME)) {
+		err("I2S Audio ports in use");
+	}
+
+	/* Allocate the DMA Channels
+	*/
+	if ((s->dma_dac.dmanr = au1xxx_dbdma_chan_alloc(DBDMA_MEM_CHAN,
+	    DBDMA_I2S_TX_CHAN, dac_dma_interrupt, (void *)s)) == 0) {
+		err("Can't get DAC DMA");
+		goto err_dma1;
+	}
+	au1xxx_dbdma_set_devwidth(s->dma_dac.dmanr, 16);
+	if (au1xxx_dbdma_ring_alloc(s->dma_dac.dmanr,
+					NUM_DBDMA_DESCRIPTORS) == 0) {
+		err("Can't get DAC DMA descriptors");
+		goto err_dma1;
+	}
+
+	if ((s->dma_adc.dmanr = au1xxx_dbdma_chan_alloc(DBDMA_I2S_RX_CHAN,
+	    DBDMA_MEM_CHAN, adc_dma_interrupt, (void *)s)) == 0) {
+		err("Can't get ADC DMA");
+		goto err_dma2;
+	}
+	au1xxx_dbdma_set_devwidth(s->dma_adc.dmanr, 16);
+	if (au1xxx_dbdma_ring_alloc(s->dma_adc.dmanr,
+					NUM_DBDMA_DESCRIPTORS) == 0) {
+		err("Can't get ADC DMA descriptors");
+		goto err_dma2;
+	}
+
+	info("DAC: DMA%d, ADC: DMA%d", DBDMA_I2S_TX_CHAN, DBDMA_I2S_RX_CHAN);
+
+	/* register devices */
+
+	if ((s->dev_audio = register_sound_dsp(&au1550_audio_fops, -1)) < 0)
+		goto err_dev1;
+#if 0
+	if ((s->codec->dev_mixer =
+	     register_sound_mixer(&au1550_mixer_fops, -1)) < 0)
+		goto err_dev2;
+#endif
+
+#ifdef AU1550_DEBUG
+	/* intialize the debug proc device */
+	s->ps = create_proc_read_entry(AU1000_MODULE_NAME, 0, NULL,
+				       proc_au1550_dump, NULL);
+#endif /* AU1550_DEBUG */
+
+	intclk_setup();
+
+	/* The GPIO for the appropriate PSC was configured by the
+	 * board specific start up.
+	 *
+	 * configure PSC for I2S Audio
+	 */
+	ip->psc_ctrl = PSC_CTRL_DISABLE;	/* Disable PSC */
+	au_sync();
+	ip->psc_sel = (PSC_SEL_CLK_INTCLK | PSC_SEL_PS_I2SMODE);
+	au_sync();
+
+	/* Enable PSC
+	*/
+	ip->psc_ctrl = PSC_CTRL_ENABLE;
+	au_sync();
+
+	/* Wait for PSC ready.
+	*/
+	do {
+		val = ip->psc_i2sstat;
+		au_sync();
+	} while ((val & PSC_I2SSTAT_SR) == 0);
+
+	/* Configure I2S controller.
+	 * Deep FIFO, 16-bit sample, DMA, make sure DMA matches fifo size.
+	 * Actual I2S mode (first bit delayed by one clock).
+	 * Master mode (We provide the clock from the PSC).
+	 */
+	val = PSC_I2SCFG_SET_LEN(16);
+#ifdef TRY_441KHz
+	/* This really should be 250, but it appears that all of the
+	 * PLLs, dividers and so on in the chain shift it.  That's the
+	 * problem with sourceing the clock instead of letting the very
+	 * stable codec provide it.  But, the PSC doesn't appear to want
+	 * to work in slave mode, so this is what we get.  It's  not
+	 * studio quality timing, but it's good enough for listening
+	 * to mp3s.
+	 */
+	val |= PSC_I2SCFG_SET_WS(252);
+#else
+	val |= PSC_I2SCFG_SET_WS(250);
+#endif
+	val |= PSC_I2SCFG_RT_FIFO8 | PSC_I2SCFG_TT_FIFO8 | \
+					PSC_I2SCFG_BI | PSC_I2SCFG_XM;
+
+	ip->psc_i2scfg = val;
+	au_sync();
+	val |= PSC_I2SCFG_DE_ENABLE;
+	ip->psc_i2scfg = val;
+	au_sync();
+
+	/* Wait for Device ready.
+	*/
+	do {
+		val = ip->psc_i2sstat;
+		au_sync();
+	} while ((val & PSC_I2SSTAT_DR) == 0);
+
+	val = ip->psc_i2scfg;
+	au_sync();
+
+	codec_init();
+
+	s->no_vra = 1;
+	if (s->no_vra)
+		info("no VRA, interpolating and decimating");
+
+#if 0
+	/* set mic to be the recording source */
+	val = SOUND_MASK_MIC;
+	mixdev_ioctl(s->codec, SOUND_MIXER_WRITE_RECSRC,
+		     (unsigned long) &val);
+#ifdef AU1550_DEBUG
+	sprintf(proc_str, "driver/%s/%d/ac97", AU1550_MODULE_NAME,
+		s->codec->id);
+	s->ac97_ps = create_proc_read_entry (proc_str, 0, NULL,
+					     ac97_read_proc, &s->codec);
+#endif
+#endif
+
+	return 0;
+
+#if 0
+ err_dev3:
+	unregister_sound_mixer(s->codec->dev_mixer);
+ err_dev2:
+	unregister_sound_dsp(s->dev_audio);
+#endif
+ err_dev1:
+	au1xxx_dbdma_chan_free(s->dma_adc.dmanr);
+ err_dma2:
+	au1xxx_dbdma_chan_free(s->dma_dac.dmanr);
+ err_dma1:
+	release_region(PHYSADDR(I2S_PSC_BASE), 0x30);
+
+	return -1;
+}
+
+static void __devinit
+au1550_remove(void)
+{
+	struct au1550_state *s = &au1550_state;
+
+	if (!s)
+		return;
+#ifdef AU1550_DEBUG
+	if (s->ps)
+		remove_proc_entry(AU1000_MODULE_NAME, NULL);
+#endif /* AU1000_DEBUG */
+	synchronize_irq();
+	au1xxx_dbdma_chan_free(s->dma_adc.dmanr);
+	au1xxx_dbdma_chan_free(s->dma_dac.dmanr);
+	release_region(PHYSADDR(I2S_PSC_BASE), 0x30);
+	unregister_sound_dsp(s->dev_audio);
+#if 0
+	unregister_sound_mixer(s->codec->dev_mixer);
+#endif
+}
+
+static int __init
+init_au1550(void)
+{
+	return au1550_probe();
+}
+
+static void __exit
+cleanup_au1550(void)
+{
+	au1550_remove();
+}
+
+module_init(init_au1550);
+module_exit(cleanup_au1550);
+
+#ifndef MODULE
+
+static int __init
+au1550_setup(char *options)
+{
+	char           *this_opt;
+
+	if (!options || !*options)
+		return 0;
+
+	for(this_opt=strtok(options, ",");
+	    this_opt; this_opt=strtok(NULL, ",")) {
+		if (!strncmp(this_opt, "vra", 3)) {
+			vra = 1;
+		}
+	}
+
+	return 1;
+}
+
+__setup("au1550_audio=", au1550_setup);
+
+#endif /* MODULE */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/sound/au1550_psc.c linux-2.4.29-pre3/drivers/sound/au1550_psc.c
--- linux-2.4.28/drivers/sound/au1550_psc.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/drivers/sound/au1550_psc.c	2004-12-22 16:05:33.114385176 +0000
@@ -0,0 +1,2168 @@
+/*
+ *      au1550.c  --  Sound driver for Alchemy Au1550 MIPS Internet Edge
+ *                    Processor.
+ *
+ * Copyright 2004 Embedded Edge, LLC
+ *	dan@embeddededge.com
+ *
+ * Mostly copied from the au1000.c driver and some from the
+ * PowerMac dbdma driver.
+ * We assume the processor can do memory coherent DMA.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/sound.h>
+#include <linux/slab.h>
+#include <linux/soundcard.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/pci.h>
+#include <linux/bitops.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
+#include <linux/ac97_codec.h>
+#include <linux/wrapper.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/hardirq.h>
+#include <asm/au1000.h>
+#include <asm/au1xxx_psc.h>
+#include <asm/au1xxx_dbdma.h>
+
+#ifdef CONFIG_MIPS_PB1550
+#include <asm/pb1550.h>
+#endif
+
+#ifdef CONFIG_MIPS_DB1550
+#include <asm/db1x00.h>
+#endif
+
+#undef OSS_DOCUMENTED_MIXER_SEMANTICS
+
+#define AU1550_MODULE_NAME "Au1550 psc audio"
+#define PFX AU1550_MODULE_NAME
+
+/* misc stuff */
+/* #define POLL_COUNT   0x5000 */
+#define POLL_COUNT   0x50000
+#define AC97_EXT_DACS (AC97_EXTID_SDAC | AC97_EXTID_CDAC | AC97_EXTID_LDAC)
+
+/* The number of DBDMA ring descriptors to allocate.  No sense making
+ * this too large....if you can't keep up with a few you aren't likely
+ * to be able to with lots of them, either.
+ */
+#define NUM_DBDMA_DESCRIPTORS 4
+
+#define err(format, arg...) printk(KERN_ERR PFX ": " format "\n" , ## arg)
+#define info(format, arg...) printk(KERN_INFO PFX ": " format "\n" , ## arg)
+
+/* Boot options
+ * 0 = no VRA, 1 = use VRA if codec supports it
+ */
+static int      vra = 1;
+MODULE_PARM(vra, "i");
+MODULE_PARM_DESC(vra, "if 1 use VRA if codec supports it");
+
+static struct au1550_state {
+	/* soundcore stuff */
+	int             dev_audio;
+
+#ifdef AU1000_DEBUG
+	/* debug /proc entry */
+	struct proc_dir_entry *ps;
+	struct proc_dir_entry *ac97_ps;
+#endif				/* AU1000_DEBUG */
+
+	struct ac97_codec *codec;
+	unsigned        codec_base_caps; /* AC'97 reg 00h, "Reset Register" */
+	unsigned        codec_ext_caps;  /* AC'97 reg 28h, "Extended Audio ID" */
+	int             no_vra;		/* do not use VRA */
+
+	spinlock_t      lock;
+	struct semaphore open_sem;
+	struct semaphore sem;
+	mode_t          open_mode;
+	wait_queue_head_t open_wait;
+
+	struct dmabuf {
+		u32		dmanr;
+		unsigned        sample_rate;
+		unsigned	src_factor;
+		unsigned        sample_size;
+		int             num_channels;
+		int		dma_bytes_per_sample;
+		int		user_bytes_per_sample;
+		int		cnt_factor;
+
+		void		*rawbuf;
+		unsigned        buforder;
+		unsigned	numfrag;
+		unsigned        fragshift;
+		void		*nextIn;
+		void		*nextOut;
+		int		count;
+		unsigned        total_bytes;
+		unsigned        error;
+		wait_queue_head_t wait;
+
+		/* redundant, but makes calculations easier */
+		unsigned	fragsize;
+		unsigned	dma_fragsize;
+		unsigned	dmasize;
+		unsigned	dma_qcount;
+
+		/* OSS stuff */
+		unsigned        mapped:1;
+		unsigned        ready:1;
+		unsigned        stopped:1;
+		unsigned        ossfragshift;
+		int             ossmaxfrags;
+		unsigned        subdivision;
+	} dma_dac, dma_adc;
+} au1550_state;
+
+static unsigned
+ld2(unsigned int x)
+{
+	unsigned        r = 0;
+
+	if (x >= 0x10000) {
+		x >>= 16;
+		r += 16;
+	}
+	if (x >= 0x100) {
+		x >>= 8;
+		r += 8;
+	}
+	if (x >= 0x10) {
+		x >>= 4;
+		r += 4;
+	}
+	if (x >= 4) {
+		x >>= 2;
+		r += 2;
+	}
+	if (x >= 2)
+		r++;
+	return r;
+}
+
+static void
+au1550_delay(int msec)
+{
+	unsigned long   tmo;
+	signed long     tmo2;
+
+	if (in_interrupt())
+		return;
+
+	tmo = jiffies + (msec * HZ) / 1000;
+	for (;;) {
+		tmo2 = tmo - jiffies;
+		if (tmo2 <= 0)
+			break;
+		schedule_timeout(tmo2);
+	}
+}
+
+static u16
+rdcodec(struct ac97_codec *codec, u8 addr)
+{
+	struct au1550_state *s = (struct au1550_state *)codec->private_data;
+	unsigned long   flags;
+	u32             cmd, val;
+	u16             data;
+	int             i;
+
+	spin_lock_irqsave(&s->lock, flags);
+
+	for (i = 0; i < POLL_COUNT; i++) {
+		val = au_readl(PSC_AC97STAT);
+		au_sync();
+		if (!(val & PSC_AC97STAT_CP))
+			break;
+	}
+	if (i == POLL_COUNT)
+		err("rdcodec: codec cmd pending expired!");
+
+	cmd = (u32)PSC_AC97CDC_INDX(addr);
+	cmd |= PSC_AC97CDC_RD;	/* read command */
+	au_writel(cmd, PSC_AC97CDC);
+	au_sync();
+
+	/* now wait for the data
+	*/
+	for (i = 0; i < POLL_COUNT; i++) {
+		val = au_readl(PSC_AC97STAT);
+		au_sync();
+		if (!(val & PSC_AC97STAT_CP))
+			break;
+	}
+	if (i == POLL_COUNT) {
+		err("rdcodec: read poll expired!");
+		return 0;
+	}
+
+	/* wait for command done?
+	*/
+	for (i = 0; i < POLL_COUNT; i++) {
+		val = au_readl(PSC_AC97EVNT);
+		au_sync();
+		if (val & PSC_AC97EVNT_CD)
+			break;
+	}
+	if (i == POLL_COUNT) {
+		err("rdcodec: read cmdwait expired!");
+		return 0;
+	}
+
+	data = au_readl(PSC_AC97CDC) & 0xffff;
+	au_sync();
+
+	/* Clear command done event.
+	*/
+	au_writel(PSC_AC97EVNT_CD, PSC_AC97EVNT);
+	au_sync();
+
+	spin_unlock_irqrestore(&s->lock, flags);
+
+	return data;
+}
+
+
+static void
+wrcodec(struct ac97_codec *codec, u8 addr, u16 data)
+{
+	struct au1550_state *s = (struct au1550_state *)codec->private_data;
+	unsigned long   flags;
+	u32             cmd, val;
+	int             i;
+
+	spin_lock_irqsave(&s->lock, flags);
+
+	for (i = 0; i < POLL_COUNT; i++) {
+		val = au_readl(PSC_AC97STAT);
+		au_sync();
+		if (!(val & PSC_AC97STAT_CP))
+			break;
+	}
+	if (i == POLL_COUNT)
+		err("wrcodec: codec cmd pending expired!");
+
+	cmd = (u32)PSC_AC97CDC_INDX(addr);
+	cmd |= (u32)data;
+	au_writel(cmd, PSC_AC97CDC);
+	au_sync();
+
+	for (i = 0; i < POLL_COUNT; i++) {
+		val = au_readl(PSC_AC97STAT);
+		au_sync();
+		if (!(val & PSC_AC97STAT_CP))
+			break;
+	}
+	if (i == POLL_COUNT)
+		err("wrcodec: codec cmd pending expired!");
+
+	for (i = 0; i < POLL_COUNT; i++) {
+		val = au_readl(PSC_AC97EVNT);
+		au_sync();
+		if (val & PSC_AC97EVNT_CD)
+			break;
+	}
+	if (i == POLL_COUNT)
+		err("wrcodec: read cmdwait expired!");
+
+	/* Clear command done event.
+	*/
+	au_writel(PSC_AC97EVNT_CD, PSC_AC97EVNT);
+	au_sync();
+
+	spin_unlock_irqrestore(&s->lock, flags);
+}
+
+static void
+waitcodec(struct ac97_codec *codec)
+{
+	u16	temp;
+	u32	val;
+	int	i;
+
+	/* codec_wait is used to wait for a ready state after
+	 * an AC97C_RESET.
+	 */
+	au1550_delay(10);
+
+	/* first poll the CODEC_READY tag bit
+	*/
+	for (i = 0; i < POLL_COUNT; i++) {
+		val = au_readl(PSC_AC97STAT);
+		au_sync();
+		if (val & PSC_AC97STAT_CR)
+			break;
+	}
+	if (i == POLL_COUNT) {
+		err("waitcodec: CODEC_READY poll expired!");
+		return;
+	}
+
+	/* get AC'97 powerdown control/status register
+	*/
+	temp = rdcodec(codec, AC97_POWER_CONTROL);
+
+	/* If anything is powered down, power'em up
+	*/
+	if (temp & 0x7f00) {
+		/* Power on
+		*/
+		wrcodec(codec, AC97_POWER_CONTROL, 0);
+		au1550_delay(100);
+
+		/* Reread
+		*/
+		temp = rdcodec(codec, AC97_POWER_CONTROL);
+	}
+    
+	/* Check if Codec REF,ANL,DAC,ADC ready
+	*/
+	if ((temp & 0x7f0f) != 0x000f)
+		err("codec reg 26 status (0x%x) not ready!!", temp);
+}
+
+/* stop the ADC before calling */
+static void
+set_adc_rate(struct au1550_state *s, unsigned rate)
+{
+	struct dmabuf  *adc = &s->dma_adc;
+	struct dmabuf  *dac = &s->dma_dac;
+	unsigned        adc_rate, dac_rate;
+	u16             ac97_extstat;
+
+	if (s->no_vra) {
+		/* calc SRC factor
+		*/
+		adc->src_factor = ((96000 / rate) + 1) >> 1;
+		adc->sample_rate = 48000 / adc->src_factor;
+		return;
+	}
+
+	adc->src_factor = 1;
+
+	ac97_extstat = rdcodec(s->codec, AC97_EXTENDED_STATUS);
+
+	rate = rate > 48000 ? 48000 : rate;
+
+	/* enable VRA
+	*/
+	wrcodec(s->codec, AC97_EXTENDED_STATUS,
+		ac97_extstat | AC97_EXTSTAT_VRA);
+
+	/* now write the sample rate
+	*/
+	wrcodec(s->codec, AC97_PCM_LR_ADC_RATE, (u16) rate);
+
+	/* read it back for actual supported rate
+	*/
+	adc_rate = rdcodec(s->codec, AC97_PCM_LR_ADC_RATE);
+
+#ifdef AU1000_VERBOSE_DEBUG
+	dbg(__FUNCTION__ ": set to %d Hz", adc_rate);
+#endif
+
+	/* some codec's don't allow unequal DAC and ADC rates, in which case
+	 * writing one rate reg actually changes both.
+	 */
+	dac_rate = rdcodec(s->codec, AC97_PCM_FRONT_DAC_RATE);
+	if (dac->num_channels > 2)
+		wrcodec(s->codec, AC97_PCM_SURR_DAC_RATE, dac_rate);
+	if (dac->num_channels > 4)
+		wrcodec(s->codec, AC97_PCM_LFE_DAC_RATE, dac_rate);
+
+	adc->sample_rate = adc_rate;
+	dac->sample_rate = dac_rate;
+}
+
+/* stop the DAC before calling */
+static void
+set_dac_rate(struct au1550_state *s, unsigned rate)
+{
+	struct dmabuf  *dac = &s->dma_dac;
+	struct dmabuf  *adc = &s->dma_adc;
+	unsigned        adc_rate, dac_rate;
+	u16             ac97_extstat;
+
+	if (s->no_vra) {
+		/* calc SRC factor
+		*/
+		dac->src_factor = ((96000 / rate) + 1) >> 1;
+		dac->sample_rate = 48000 / dac->src_factor;
+		return;
+	}
+
+	dac->src_factor = 1;
+
+	ac97_extstat = rdcodec(s->codec, AC97_EXTENDED_STATUS);
+
+	rate = rate > 48000 ? 48000 : rate;
+
+	/* enable VRA
+	*/
+	wrcodec(s->codec, AC97_EXTENDED_STATUS,
+		ac97_extstat | AC97_EXTSTAT_VRA);
+
+	/* now write the sample rate
+	*/
+	wrcodec(s->codec, AC97_PCM_FRONT_DAC_RATE, (u16) rate);
+
+	/* I don't support different sample rates for multichannel,
+	 * so make these channels the same.
+	 */
+	if (dac->num_channels > 2)
+		wrcodec(s->codec, AC97_PCM_SURR_DAC_RATE, (u16) rate);
+	if (dac->num_channels > 4)
+		wrcodec(s->codec, AC97_PCM_LFE_DAC_RATE, (u16) rate);
+	/* read it back for actual supported rate
+	*/
+	dac_rate = rdcodec(s->codec, AC97_PCM_FRONT_DAC_RATE);
+
+#ifdef AU1000_VERBOSE_DEBUG
+	dbg(__FUNCTION__ ": set to %d Hz", dac_rate);
+#endif
+
+	/* some codec's don't allow unequal DAC and ADC rates, in which case
+	 * writing one rate reg actually changes both.
+	 */
+	adc_rate = rdcodec(s->codec, AC97_PCM_LR_ADC_RATE);
+
+	dac->sample_rate = dac_rate;
+	adc->sample_rate = adc_rate;
+}
+
+static void
+stop_dac(struct au1550_state *s)
+{
+	struct dmabuf  *db = &s->dma_dac;
+	u32		stat;
+	unsigned long   flags;
+
+	if (db->stopped)
+		return;
+
+	spin_lock_irqsave(&s->lock, flags);
+
+	au_writel(PSC_AC97PCR_TP, PSC_AC97PCR);
+	au_sync();
+
+	/* Wait for Transmit Busy to show disabled.
+	*/
+	do {
+		stat = readl(PSC_AC97STAT);
+		au_sync();
+	} while ((stat & PSC_AC97STAT_TB) != 0);
+
+	au1xxx_dbdma_reset(db->dmanr);
+
+	db->stopped = 1;
+
+	spin_unlock_irqrestore(&s->lock, flags);
+}
+
+static void
+stop_adc(struct au1550_state *s)
+{
+	struct dmabuf  *db = &s->dma_adc;
+	unsigned long   flags;
+	u32		stat;
+
+	if (db->stopped)
+		return;
+
+	spin_lock_irqsave(&s->lock, flags);
+
+	au_writel(PSC_AC97PCR_RP, PSC_AC97PCR);
+	au_sync();
+
+	/* Wait for Receive Busy to show disabled.
+	*/
+	do {
+		stat = readl(PSC_AC97STAT);
+		au_sync();
+	} while ((stat & PSC_AC97STAT_RB) != 0);
+
+	au1xxx_dbdma_reset(db->dmanr);
+
+	db->stopped = 1;
+
+	spin_unlock_irqrestore(&s->lock, flags);
+}
+
+
+static void
+set_xmit_slots(int num_channels)
+{
+	u32	ac97_config, stat;
+
+	ac97_config = au_readl(PSC_AC97CFG);
+	au_sync();
+	ac97_config &= ~(PSC_AC97CFG_TXSLOT_MASK | PSC_AC97CFG_DE_ENABLE);
+	au_writel(ac97_config, PSC_AC97CFG);
+	au_sync();
+
+	switch (num_channels) {
+	case 6:		/* stereo with surround and center/LFE,
+			 * slots 3,4,6,7,8,9
+			 */
+		ac97_config |= PSC_AC97CFG_TXSLOT_ENA(6);
+		ac97_config |= PSC_AC97CFG_TXSLOT_ENA(9);
+
+	case 4:		/* stereo with surround, slots 3,4,7,8 */
+		ac97_config |= PSC_AC97CFG_TXSLOT_ENA(7);
+		ac97_config |= PSC_AC97CFG_TXSLOT_ENA(8);
+
+	case 2:		/* stereo, slots 3,4 */
+	case 1:		/* mono */
+		ac97_config |= PSC_AC97CFG_TXSLOT_ENA(3);
+		ac97_config |= PSC_AC97CFG_TXSLOT_ENA(4);
+	}
+
+	au_writel(ac97_config, PSC_AC97CFG);
+	au_sync();
+
+	ac97_config |= PSC_AC97CFG_DE_ENABLE;
+	au_writel(ac97_config, PSC_AC97CFG);
+	au_sync();
+
+	/* Wait for Device ready.
+	*/
+	do {
+		stat = readl(PSC_AC97STAT);
+		au_sync();
+	} while ((stat & PSC_AC97STAT_DR) == 0);
+}
+
+static void
+set_recv_slots(int num_channels)
+{
+	u32	ac97_config, stat;
+
+	ac97_config = au_readl(PSC_AC97CFG);
+	au_sync();
+	ac97_config &= ~(PSC_AC97CFG_RXSLOT_MASK | PSC_AC97CFG_DE_ENABLE);
+	au_writel(ac97_config, PSC_AC97CFG);
+	au_sync();
+
+	/* Always enable slots 3 and 4 (stereo). Slot 6 is
+	 * optional Mic ADC, which we don't support yet.
+	 */
+	ac97_config |= PSC_AC97CFG_RXSLOT_ENA(3);
+	ac97_config |= PSC_AC97CFG_RXSLOT_ENA(4);
+
+	au_writel(ac97_config, PSC_AC97CFG);
+	au_sync();
+
+	ac97_config |= PSC_AC97CFG_DE_ENABLE;
+	au_writel(ac97_config, PSC_AC97CFG);
+	au_sync();
+
+	/* Wait for Device ready.
+	*/
+	do {
+		stat = readl(PSC_AC97STAT);
+		au_sync();
+	} while ((stat & PSC_AC97STAT_DR) == 0);
+}
+
+static void
+start_dac(struct au1550_state *s)
+{
+	struct dmabuf  *db = &s->dma_dac;
+	unsigned long   flags;
+
+	if (!db->stopped)
+		return;
+
+	spin_lock_irqsave(&s->lock, flags);
+
+	set_xmit_slots(db->num_channels);
+	au_writel(PSC_AC97PCR_TC, PSC_AC97PCR);
+	au_sync();
+	au_writel(PSC_AC97PCR_TS, PSC_AC97PCR);
+	au_sync();
+
+	au1xxx_dbdma_start(db->dmanr);
+
+	db->stopped = 0;
+
+	spin_unlock_irqrestore(&s->lock, flags);
+}
+
+static void
+start_adc(struct au1550_state *s)
+{
+	struct dmabuf  *db = &s->dma_adc;
+	int	i;
+
+	if (!db->stopped)
+		return;
+
+	/* Put two buffers on the ring to get things started.
+	*/
+	for (i=0; i<2; i++) {
+		au1xxx_dbdma_put_dest(db->dmanr, db->nextIn, db->dma_fragsize);
+
+		db->nextIn += db->dma_fragsize;
+		if (db->nextIn >= db->rawbuf + db->dmasize)
+			db->nextIn -= db->dmasize;
+	}
+
+	set_recv_slots(db->num_channels);
+	au1xxx_dbdma_start(db->dmanr);
+	au_writel(PSC_AC97PCR_RC, PSC_AC97PCR);
+	au_sync();
+	au_writel(PSC_AC97PCR_RS, PSC_AC97PCR);
+	au_sync();
+
+	db->stopped = 0;
+}
+
+static int
+prog_dmabuf(struct au1550_state *s, struct dmabuf *db)
+{
+	unsigned user_bytes_per_sec;
+	unsigned        bufs;
+	unsigned        rate = db->sample_rate;
+
+	if (!db->rawbuf) {
+		db->ready = db->mapped = 0;
+		db->buforder = 5;	/* 32 * PAGE_SIZE */
+		db->rawbuf = kmalloc((PAGE_SIZE << db->buforder), GFP_KERNEL);
+		if (!db->rawbuf)
+			return -ENOMEM;
+	}
+
+	db->cnt_factor = 1;
+	if (db->sample_size == 8)
+		db->cnt_factor *= 2;
+	if (db->num_channels == 1)
+		db->cnt_factor *= 2;
+	db->cnt_factor *= db->src_factor;
+
+	db->count = 0;
+	db->dma_qcount = 0;
+	db->nextIn = db->nextOut = db->rawbuf;
+
+	db->user_bytes_per_sample = (db->sample_size>>3) * db->num_channels;
+	db->dma_bytes_per_sample = 2 * ((db->num_channels == 1) ?
+					2 : db->num_channels);
+
+	user_bytes_per_sec = rate * db->user_bytes_per_sample;
+	bufs = PAGE_SIZE << db->buforder;
+	if (db->ossfragshift) {
+		if ((1000 << db->ossfragshift) < user_bytes_per_sec)
+			db->fragshift = ld2(user_bytes_per_sec/1000);
+		else
+			db->fragshift = db->ossfragshift;
+	} else {
+		db->fragshift = ld2(user_bytes_per_sec / 100 /
+				    (db->subdivision ? db->subdivision : 1));
+		if (db->fragshift < 3)
+			db->fragshift = 3;
+	}
+
+	db->fragsize = 1 << db->fragshift;
+	db->dma_fragsize = db->fragsize * db->cnt_factor;
+	db->numfrag = bufs / db->dma_fragsize;
+
+	while (db->numfrag < 4 && db->fragshift > 3) {
+		db->fragshift--;
+		db->fragsize = 1 << db->fragshift;
+		db->dma_fragsize = db->fragsize * db->cnt_factor;
+		db->numfrag = bufs / db->dma_fragsize;
+	}
+
+	if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
+		db->numfrag = db->ossmaxfrags;
+
+	db->dmasize = db->dma_fragsize * db->numfrag;
+	memset(db->rawbuf, 0, bufs);
+
+#ifdef AU1000_VERBOSE_DEBUG
+	dbg("rate=%d, samplesize=%d, channels=%d",
+	    rate, db->sample_size, db->num_channels);
+	dbg("fragsize=%d, cnt_factor=%d, dma_fragsize=%d",
+	    db->fragsize, db->cnt_factor, db->dma_fragsize);
+	dbg("numfrag=%d, dmasize=%d", db->numfrag, db->dmasize);
+#endif
+
+	db->ready = 1;
+	return 0;
+}
+
+static int
+prog_dmabuf_adc(struct au1550_state *s)
+{
+	stop_adc(s);
+	return prog_dmabuf(s, &s->dma_adc);
+
+}
+
+static int
+prog_dmabuf_dac(struct au1550_state *s)
+{
+	stop_dac(s);
+	return prog_dmabuf(s, &s->dma_dac);
+}
+
+
+/* hold spinlock for the following */
+static void
+dac_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct au1550_state *s = (struct au1550_state *) dev_id;
+	struct dmabuf  *db = &s->dma_dac;
+	u32	ac97c_stat;
+
+	ac97c_stat = au_readl(PSC_AC97STAT);
+#ifdef AU1000_VERBOSE_DEBUG
+	if (ac97c_stat & (AC97C_XU | AC97C_XO | AC97C_TE))
+		dbg("AC97C status = 0x%08x", ac97c_stat);
+#endif
+	db->dma_qcount--;
+
+	if (db->count >= db->fragsize) {
+		if (au1xxx_dbdma_put_source(db->dmanr, db->nextOut,
+							db->fragsize) == 0) {
+			err("qcount < 2 and no ring room!");
+		}
+		db->nextOut += db->fragsize;
+		if (db->nextOut >= db->rawbuf + db->dmasize)
+			db->nextOut -= db->dmasize;
+		db->count -= db->fragsize;
+		db->total_bytes += db->dma_fragsize;
+		db->dma_qcount++;
+	}
+
+	/* wake up anybody listening */
+	if (waitqueue_active(&db->wait))
+		wake_up(&db->wait);
+}
+
+
+static void
+adc_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct	au1550_state *s = (struct au1550_state *)dev_id;
+	struct	dmabuf  *dp = &s->dma_adc;
+	u32	obytes;
+	char	*obuf;
+
+	/* Pull the buffer from the dma queue.
+	*/
+	au1xxx_dbdma_get_dest(dp->dmanr, (void *)(&obuf), &obytes);
+
+	if ((dp->count + obytes) > dp->dmasize) {
+		/* Overrun. Stop ADC and log the error
+		*/
+		stop_adc(s);
+		dp->error++;
+		err("adc overrun");
+		return;
+	}
+
+	/* Put a new empty buffer on the destination DMA.
+	*/
+	au1xxx_dbdma_put_dest(dp->dmanr, dp->nextIn, dp->dma_fragsize);
+
+	dp->nextIn += dp->dma_fragsize;
+	if (dp->nextIn >= dp->rawbuf + dp->dmasize)
+		dp->nextIn -= dp->dmasize;
+
+	dp->count += obytes;
+	dp->total_bytes += obytes;
+
+	/* wake up anybody listening
+	*/
+	if (waitqueue_active(&dp->wait))
+		wake_up(&dp->wait);
+
+}
+
+static loff_t
+au1550_llseek(struct file *file, loff_t offset, int origin)
+{
+	return -ESPIPE;
+}
+
+
+static int
+au1550_open_mixdev(struct inode *inode, struct file *file)
+{
+	file->private_data = &au1550_state;
+	return 0;
+}
+
+static int
+au1550_release_mixdev(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+static int
+mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd,
+                        unsigned long arg)
+{
+	return codec->mixer_ioctl(codec, cmd, arg);
+}
+
+static int
+au1550_ioctl_mixdev(struct inode *inode, struct file *file,
+			       unsigned int cmd, unsigned long arg)
+{
+	struct au1550_state *s = (struct au1550_state *)file->private_data;
+	struct ac97_codec *codec = s->codec;
+
+	return mixdev_ioctl(codec, cmd, arg);
+}
+
+static /*const */ struct file_operations au1550_mixer_fops = {
+	owner:THIS_MODULE,
+	llseek:au1550_llseek,
+	ioctl:au1550_ioctl_mixdev,
+	open:au1550_open_mixdev,
+	release:au1550_release_mixdev,
+};
+
+static int
+drain_dac(struct au1550_state *s, int nonblock)
+{
+	unsigned long   flags;
+	int             count, tmo;
+
+	if (s->dma_dac.mapped || !s->dma_dac.ready || s->dma_dac.stopped)
+		return 0;
+
+	for (;;) {
+		spin_lock_irqsave(&s->lock, flags);
+		count = s->dma_dac.count;
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count <= s->dma_dac.fragsize)
+			break;
+		if (signal_pending(current))
+			break;
+		if (nonblock)
+			return -EBUSY;
+		tmo = 1000 * count / (s->no_vra ?
+				      48000 : s->dma_dac.sample_rate);
+		tmo /= s->dma_dac.dma_bytes_per_sample;
+		au1550_delay(tmo);
+	}
+	if (signal_pending(current))
+		return -ERESTARTSYS;
+	return 0;
+}
+
+static inline u8 S16_TO_U8(s16 ch)
+{
+	return (u8) (ch >> 8) + 0x80;
+}
+static inline s16 U8_TO_S16(u8 ch)
+{
+	return (s16) (ch - 0x80) << 8;
+}
+
+/*
+ * Translates user samples to dma buffer suitable for AC'97 DAC data:
+ *     If mono, copy left channel to right channel in dma buffer.
+ *     If 8 bit samples, cvt to 16-bit before writing to dma buffer.
+ *     If interpolating (no VRA), duplicate every audio frame src_factor times.
+ */
+static int
+translate_from_user(struct dmabuf *db, char* dmabuf, char* userbuf,
+							       int dmacount)
+{
+	int             sample, i;
+	int             interp_bytes_per_sample;
+	int             num_samples;
+	int             mono = (db->num_channels == 1);
+	char            usersample[12];
+	s16             ch, dmasample[6];
+
+	if (db->sample_size == 16 && !mono && db->src_factor == 1) {
+		/* no translation necessary, just copy
+		*/
+		if (copy_from_user(dmabuf, userbuf, dmacount))
+			return -EFAULT;
+		return dmacount;
+	}
+
+	interp_bytes_per_sample = db->dma_bytes_per_sample * db->src_factor;
+	num_samples = dmacount / interp_bytes_per_sample;
+
+	for (sample = 0; sample < num_samples; sample++) {
+		if (copy_from_user(usersample, userbuf,
+				   db->user_bytes_per_sample)) {
+			return -EFAULT;
+		}
+
+		for (i = 0; i < db->num_channels; i++) {
+			if (db->sample_size == 8)
+				ch = U8_TO_S16(usersample[i]);
+			else
+				ch = *((s16 *) (&usersample[i * 2]));
+			dmasample[i] = ch;
+			if (mono)
+				dmasample[i + 1] = ch;	/* right channel */
+		}
+
+		/* duplicate every audio frame src_factor times
+		*/
+		for (i = 0; i < db->src_factor; i++)
+			memcpy(dmabuf, dmasample, db->dma_bytes_per_sample);
+
+		userbuf += db->user_bytes_per_sample;
+		dmabuf += interp_bytes_per_sample;
+	}
+
+	return num_samples * interp_bytes_per_sample;
+}
+
+/*
+ * Translates AC'97 ADC samples to user buffer:
+ *     If mono, send only left channel to user buffer.
+ *     If 8 bit samples, cvt from 16 to 8 bit before writing to user buffer.
+ *     If decimating (no VRA), skip over src_factor audio frames.
+ */
+static int
+translate_to_user(struct dmabuf *db, char* userbuf, char* dmabuf,
+							     int dmacount)
+{
+	int             sample, i;
+	int             interp_bytes_per_sample;
+	int             num_samples;
+	int             mono = (db->num_channels == 1);
+	char            usersample[12];
+
+	if (db->sample_size == 16 && !mono && db->src_factor == 1) {
+		/* no translation necessary, just copy
+		*/
+		if (copy_to_user(userbuf, dmabuf, dmacount))
+			return -EFAULT;
+		return dmacount;
+	}
+
+	interp_bytes_per_sample = db->dma_bytes_per_sample * db->src_factor;
+	num_samples = dmacount / interp_bytes_per_sample;
+
+	for (sample = 0; sample < num_samples; sample++) {
+		for (i = 0; i < db->num_channels; i++) {
+			if (db->sample_size == 8)
+				usersample[i] =
+					S16_TO_U8(*((s16 *) (&dmabuf[i * 2])));
+			else
+				*((s16 *) (&usersample[i * 2])) =
+					*((s16 *) (&dmabuf[i * 2]));
+		}
+
+		if (copy_to_user(userbuf, usersample,
+				 db->user_bytes_per_sample)) {
+			return -EFAULT;
+		}
+
+		userbuf += db->user_bytes_per_sample;
+		dmabuf += interp_bytes_per_sample;
+	}
+
+	return num_samples * interp_bytes_per_sample;
+}
+
+/*
+ * Copy audio data to/from user buffer from/to dma buffer, taking care
+ * that we wrap when reading/writing the dma buffer. Returns actual byte
+ * count written to or read from the dma buffer.
+ */
+static int
+copy_dmabuf_user(struct dmabuf *db, char* userbuf, int count, int to_user)
+{
+	char           *bufptr = to_user ? db->nextOut : db->nextIn;
+	char           *bufend = db->rawbuf + db->dmasize;
+	int             cnt, ret;
+
+	if (bufptr + count > bufend) {
+		int             partial = (int) (bufend - bufptr);
+		if (to_user) {
+			if ((cnt = translate_to_user(db, userbuf,
+						     bufptr, partial)) < 0)
+				return cnt;
+			ret = cnt;
+			if ((cnt = translate_to_user(db, userbuf + partial,
+						     db->rawbuf,
+						     count - partial)) < 0)
+				return cnt;
+			ret += cnt;
+		} else {
+			if ((cnt = translate_from_user(db, bufptr, userbuf,
+						       partial)) < 0)
+				return cnt;
+			ret = cnt;
+			if ((cnt = translate_from_user(db, db->rawbuf,
+						       userbuf + partial,
+						       count - partial)) < 0)
+				return cnt;
+			ret += cnt;
+		}
+	} else {
+		if (to_user)
+			ret = translate_to_user(db, userbuf, bufptr, count);
+		else
+			ret = translate_from_user(db, bufptr, userbuf, count);
+	}
+
+	return ret;
+}
+
+
+static ssize_t
+au1550_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+{
+	struct au1550_state *s = (struct au1550_state *)file->private_data;
+	struct dmabuf  *db = &s->dma_adc;
+	DECLARE_WAITQUEUE(wait, current);
+	ssize_t         ret;
+	unsigned long   flags;
+	int             cnt, usercnt, avail;
+
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+	if (db->mapped)
+		return -ENXIO;
+	if (!access_ok(VERIFY_WRITE, buffer, count))
+		return -EFAULT;
+	ret = 0;
+
+	count *= db->cnt_factor;
+
+	down(&s->sem);
+	add_wait_queue(&db->wait, &wait);
+
+	while (count > 0) {
+		/* wait for samples in ADC dma buffer
+		*/
+		do {
+			if (db->stopped)
+				start_adc(s);
+			spin_lock_irqsave(&s->lock, flags);
+			avail = db->count;
+			if (avail <= 0)
+				__set_current_state(TASK_INTERRUPTIBLE);
+			spin_unlock_irqrestore(&s->lock, flags);
+			if (avail <= 0) {
+				if (file->f_flags & O_NONBLOCK) {
+					if (!ret)
+						ret = -EAGAIN;
+					goto out;
+				}
+				up(&s->sem);
+				schedule();
+				if (signal_pending(current)) {
+					if (!ret)
+						ret = -ERESTARTSYS;
+					goto out2;
+				}
+				down(&s->sem);
+			}
+		} while (avail <= 0);
+
+		/* copy from nextOut to user
+		*/
+		if ((cnt = copy_dmabuf_user(db, buffer,
+					    count > avail ?
+					    avail : count, 1)) < 0) {
+			if (!ret)
+				ret = -EFAULT;
+			goto out;
+		}
+
+		spin_lock_irqsave(&s->lock, flags);
+		db->count -= cnt;
+		db->nextOut += cnt;
+		if (db->nextOut >= db->rawbuf + db->dmasize)
+			db->nextOut -= db->dmasize;
+		spin_unlock_irqrestore(&s->lock, flags);
+
+		count -= cnt;
+		usercnt = cnt / db->cnt_factor;
+		buffer += usercnt;
+		ret += usercnt;
+	}			/* while (count > 0) */
+
+out:
+	up(&s->sem);
+out2:
+	remove_wait_queue(&db->wait, &wait);
+	set_current_state(TASK_RUNNING);
+	return ret;
+}
+
+static ssize_t
+au1550_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
+{
+	struct au1550_state *s = (struct au1550_state *)file->private_data;
+	struct dmabuf  *db = &s->dma_dac;
+	DECLARE_WAITQUEUE(wait, current);
+	ssize_t         ret = 0;
+	unsigned long   flags;
+	int             cnt, usercnt, avail;
+
+#ifdef AU1000_VERBOSE_DEBUG
+	dbg("write: count=%d", count);
+#endif
+
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+	if (db->mapped)
+		return -ENXIO;
+	if (!access_ok(VERIFY_READ, buffer, count))
+		return -EFAULT;
+
+	count *= db->cnt_factor;
+
+	down(&s->sem);	
+	add_wait_queue(&db->wait, &wait);
+
+	while (count > 0) {
+		/* wait for space in playback buffer
+		*/
+		do {
+			spin_lock_irqsave(&s->lock, flags);
+			avail = (int) db->dmasize - db->count;
+			if (avail <= 0)
+				__set_current_state(TASK_INTERRUPTIBLE);
+			spin_unlock_irqrestore(&s->lock, flags);
+			if (avail <= 0) {
+				if (file->f_flags & O_NONBLOCK) {
+					if (!ret)
+						ret = -EAGAIN;
+					goto out;
+				}
+				up(&s->sem);
+				schedule();
+				if (signal_pending(current)) {
+					if (!ret)
+						ret = -ERESTARTSYS;
+					goto out2;
+				}
+				down(&s->sem);
+			}
+		} while (avail <= 0);
+
+		/* copy from user to nextIn
+		*/
+		if ((cnt = copy_dmabuf_user(db, (char *) buffer,
+					    count > avail ?
+					    avail : count, 0)) < 0) {
+			if (!ret)
+				ret = -EFAULT;
+			goto out;
+		}
+
+		spin_lock_irqsave(&s->lock, flags);
+		db->count += cnt;
+		db->nextIn += cnt;
+		if (db->nextIn >= db->rawbuf + db->dmasize)
+			db->nextIn -= db->dmasize;
+
+		/* If the data is available, we want to keep two buffers
+		 * on the dma queue.  If the queue count reaches zero,
+		 * we know the dma has stopped.
+		 */
+		while ((db->dma_qcount < 2) && (db->count >= db->fragsize)) {
+			if (au1xxx_dbdma_put_source(db->dmanr, db->nextOut,
+							db->fragsize) == 0) {
+				err("qcount < 2 and no ring room!");
+			}
+			db->nextOut += db->fragsize;
+			if (db->nextOut >= db->rawbuf + db->dmasize)
+				db->nextOut -= db->dmasize;
+			db->total_bytes += db->dma_fragsize;
+			if (db->dma_qcount == 0)
+				start_dac(s);
+			db->dma_qcount++;
+		}
+		spin_unlock_irqrestore(&s->lock, flags);
+
+		count -= cnt;
+		usercnt = cnt / db->cnt_factor;
+		buffer += usercnt;
+		ret += usercnt;
+	}			/* while (count > 0) */
+
+out:
+	up(&s->sem);
+out2:
+	remove_wait_queue(&db->wait, &wait);
+	set_current_state(TASK_RUNNING);
+	return ret;
+}
+
+
+/* No kernel lock - we have our own spinlock */
+static unsigned int
+au1550_poll(struct file *file, struct poll_table_struct *wait)
+{
+	struct au1550_state *s = (struct au1550_state *)file->private_data;
+	unsigned long   flags;
+	unsigned int    mask = 0;
+
+	if (file->f_mode & FMODE_WRITE) {
+		if (!s->dma_dac.ready)
+			return 0;
+		poll_wait(file, &s->dma_dac.wait, wait);
+	}
+	if (file->f_mode & FMODE_READ) {
+		if (!s->dma_adc.ready)
+			return 0;
+		poll_wait(file, &s->dma_adc.wait, wait);
+	}
+
+	spin_lock_irqsave(&s->lock, flags);
+	
+	if (file->f_mode & FMODE_READ) {
+		if (s->dma_adc.count >= (signed)s->dma_adc.dma_fragsize)
+			mask |= POLLIN | POLLRDNORM;
+	}
+	if (file->f_mode & FMODE_WRITE) {
+		if (s->dma_dac.mapped) {
+			if (s->dma_dac.count >=
+			    (signed)s->dma_dac.dma_fragsize) 
+				mask |= POLLOUT | POLLWRNORM;
+		} else {
+			if ((signed) s->dma_dac.dmasize >=
+			    s->dma_dac.count + (signed)s->dma_dac.dma_fragsize)
+				mask |= POLLOUT | POLLWRNORM;
+		}
+	}
+	spin_unlock_irqrestore(&s->lock, flags);
+	return mask;
+}
+
+static int
+au1550_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	struct au1550_state *s = (struct au1550_state *)file->private_data;
+	struct dmabuf  *db;
+	unsigned long   size;
+	int ret = 0;
+
+	lock_kernel();
+	down(&s->sem);
+	if (vma->vm_flags & VM_WRITE)
+		db = &s->dma_dac;
+	else if (vma->vm_flags & VM_READ)
+		db = &s->dma_adc;
+	else {
+		ret = -EINVAL;
+		goto out;
+	}
+	if (vma->vm_pgoff != 0) {
+		ret = -EINVAL;
+		goto out;
+	}
+	size = vma->vm_end - vma->vm_start;
+	if (size > (PAGE_SIZE << db->buforder)) {
+		ret = -EINVAL;
+		goto out;
+	}
+	if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf),
+			     size, vma->vm_page_prot)) {
+		ret = -EAGAIN;
+		goto out;
+	}
+	vma->vm_flags &= ~VM_IO;
+	db->mapped = 1;
+out:
+	up(&s->sem);
+	unlock_kernel();
+	return ret;
+}
+
+
+#ifdef AU1000_VERBOSE_DEBUG
+static struct ioctl_str_t {
+	unsigned int    cmd;
+	const char     *str;
+} ioctl_str[] = {
+	{SNDCTL_DSP_RESET, "SNDCTL_DSP_RESET"},
+	{SNDCTL_DSP_SYNC, "SNDCTL_DSP_SYNC"},
+	{SNDCTL_DSP_SPEED, "SNDCTL_DSP_SPEED"},
+	{SNDCTL_DSP_STEREO, "SNDCTL_DSP_STEREO"},
+	{SNDCTL_DSP_GETBLKSIZE, "SNDCTL_DSP_GETBLKSIZE"},
+	{SNDCTL_DSP_SAMPLESIZE, "SNDCTL_DSP_SAMPLESIZE"},
+	{SNDCTL_DSP_CHANNELS, "SNDCTL_DSP_CHANNELS"},
+	{SOUND_PCM_WRITE_CHANNELS, "SOUND_PCM_WRITE_CHANNELS"},
+	{SOUND_PCM_WRITE_FILTER, "SOUND_PCM_WRITE_FILTER"},
+	{SNDCTL_DSP_POST, "SNDCTL_DSP_POST"},
+	{SNDCTL_DSP_SUBDIVIDE, "SNDCTL_DSP_SUBDIVIDE"},
+	{SNDCTL_DSP_SETFRAGMENT, "SNDCTL_DSP_SETFRAGMENT"},
+	{SNDCTL_DSP_GETFMTS, "SNDCTL_DSP_GETFMTS"},
+	{SNDCTL_DSP_SETFMT, "SNDCTL_DSP_SETFMT"},
+	{SNDCTL_DSP_GETOSPACE, "SNDCTL_DSP_GETOSPACE"},
+	{SNDCTL_DSP_GETISPACE, "SNDCTL_DSP_GETISPACE"},
+	{SNDCTL_DSP_NONBLOCK, "SNDCTL_DSP_NONBLOCK"},
+	{SNDCTL_DSP_GETCAPS, "SNDCTL_DSP_GETCAPS"},
+	{SNDCTL_DSP_GETTRIGGER, "SNDCTL_DSP_GETTRIGGER"},
+	{SNDCTL_DSP_SETTRIGGER, "SNDCTL_DSP_SETTRIGGER"},
+	{SNDCTL_DSP_GETIPTR, "SNDCTL_DSP_GETIPTR"},
+	{SNDCTL_DSP_GETOPTR, "SNDCTL_DSP_GETOPTR"},
+	{SNDCTL_DSP_MAPINBUF, "SNDCTL_DSP_MAPINBUF"},
+	{SNDCTL_DSP_MAPOUTBUF, "SNDCTL_DSP_MAPOUTBUF"},
+	{SNDCTL_DSP_SETSYNCRO, "SNDCTL_DSP_SETSYNCRO"},
+	{SNDCTL_DSP_SETDUPLEX, "SNDCTL_DSP_SETDUPLEX"},
+	{SNDCTL_DSP_GETODELAY, "SNDCTL_DSP_GETODELAY"},
+	{SNDCTL_DSP_GETCHANNELMASK, "SNDCTL_DSP_GETCHANNELMASK"},
+	{SNDCTL_DSP_BIND_CHANNEL, "SNDCTL_DSP_BIND_CHANNEL"},
+	{OSS_GETVERSION, "OSS_GETVERSION"},
+	{SOUND_PCM_READ_RATE, "SOUND_PCM_READ_RATE"},
+	{SOUND_PCM_READ_CHANNELS, "SOUND_PCM_READ_CHANNELS"},
+	{SOUND_PCM_READ_BITS, "SOUND_PCM_READ_BITS"},
+	{SOUND_PCM_READ_FILTER, "SOUND_PCM_READ_FILTER"}
+};
+#endif
+
+static int
+dma_count_done(struct dmabuf *db)
+{
+	if (db->stopped)
+		return 0;
+
+	return db->dma_fragsize - au1xxx_get_dma_residue(db->dmanr);
+}
+
+
+static int
+au1550_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+							unsigned long arg)
+{
+	struct au1550_state *s = (struct au1550_state *)file->private_data;
+	unsigned long   flags;
+	audio_buf_info  abinfo;
+	count_info      cinfo;
+	int             count;
+	int             val, mapped, ret, diff;
+
+	mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
+		((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
+
+#ifdef AU1000_VERBOSE_DEBUG
+	for (count=0; count<sizeof(ioctl_str)/sizeof(ioctl_str[0]); count++) {
+		if (ioctl_str[count].cmd == cmd)
+			break;
+	}
+	if (count < sizeof(ioctl_str) / sizeof(ioctl_str[0]))
+		dbg("ioctl %s, arg=0x%lx", ioctl_str[count].str, arg);
+	else
+		dbg("ioctl 0x%x unknown, arg=0x%lx", cmd, arg);
+#endif
+
+	switch (cmd) {
+	case OSS_GETVERSION:
+		return put_user(SOUND_VERSION, (int *) arg);
+
+	case SNDCTL_DSP_SYNC:
+		if (file->f_mode & FMODE_WRITE)
+			return drain_dac(s, file->f_flags & O_NONBLOCK);
+		return 0;
+
+	case SNDCTL_DSP_SETDUPLEX:
+		return 0;
+
+	case SNDCTL_DSP_GETCAPS:
+		return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
+				DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
+
+	case SNDCTL_DSP_RESET:
+		if (file->f_mode & FMODE_WRITE) {
+			stop_dac(s);
+			synchronize_irq();
+			s->dma_dac.count = s->dma_dac.total_bytes = 0;
+			s->dma_dac.nextIn = s->dma_dac.nextOut =
+				s->dma_dac.rawbuf;
+		}
+		if (file->f_mode & FMODE_READ) {
+			stop_adc(s);
+			synchronize_irq();
+			s->dma_adc.count = s->dma_adc.total_bytes = 0;
+			s->dma_adc.nextIn = s->dma_adc.nextOut =
+				s->dma_adc.rawbuf;
+		}
+		return 0;
+
+	case SNDCTL_DSP_SPEED:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (val >= 0) {
+			if (file->f_mode & FMODE_READ) {
+				stop_adc(s);
+				set_adc_rate(s, val);
+			}
+			if (file->f_mode & FMODE_WRITE) {
+				stop_dac(s);
+				set_dac_rate(s, val);
+			}
+			if (s->open_mode & FMODE_READ)
+				if ((ret = prog_dmabuf_adc(s)))
+					return ret;
+			if (s->open_mode & FMODE_WRITE)
+				if ((ret = prog_dmabuf_dac(s)))
+					return ret;
+		}
+		return put_user((file->f_mode & FMODE_READ) ?
+				s->dma_adc.sample_rate :
+				s->dma_dac.sample_rate,
+				(int *)arg);
+
+	case SNDCTL_DSP_STEREO:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (file->f_mode & FMODE_READ) {
+			stop_adc(s);
+			s->dma_adc.num_channels = val ? 2 : 1;
+			if ((ret = prog_dmabuf_adc(s)))
+				return ret;
+		}
+		if (file->f_mode & FMODE_WRITE) {
+			stop_dac(s);
+			s->dma_dac.num_channels = val ? 2 : 1;
+			if (s->codec_ext_caps & AC97_EXT_DACS) {
+				/* disable surround and center/lfe in AC'97
+				*/
+				u16 ext_stat = rdcodec(s->codec,
+						       AC97_EXTENDED_STATUS);
+				wrcodec(s->codec, AC97_EXTENDED_STATUS,
+					ext_stat | (AC97_EXTSTAT_PRI |
+						    AC97_EXTSTAT_PRJ |
+						    AC97_EXTSTAT_PRK));
+			}
+			if ((ret = prog_dmabuf_dac(s)))
+				return ret;
+		}
+		return 0;
+
+	case SNDCTL_DSP_CHANNELS:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (val != 0) {
+			if (file->f_mode & FMODE_READ) {
+				if (val < 0 || val > 2)
+					return -EINVAL;
+				stop_adc(s);
+				s->dma_adc.num_channels = val;
+				if ((ret = prog_dmabuf_adc(s)))
+					return ret;
+			}
+			if (file->f_mode & FMODE_WRITE) {
+				switch (val) {
+				case 1:
+				case 2:
+					break;
+				case 3:
+				case 5:
+					return -EINVAL;
+				case 4:
+					if (!(s->codec_ext_caps &
+					      AC97_EXTID_SDAC))
+						return -EINVAL;
+					break;
+				case 6:
+					if ((s->codec_ext_caps &
+					     AC97_EXT_DACS) != AC97_EXT_DACS)
+						return -EINVAL;
+					break;
+				default:
+					return -EINVAL;
+				}
+
+				stop_dac(s);
+				if (val <= 2 &&
+				    (s->codec_ext_caps & AC97_EXT_DACS)) {
+					/* disable surround and center/lfe
+					 * channels in AC'97
+					 */
+					u16             ext_stat =
+						rdcodec(s->codec,
+							AC97_EXTENDED_STATUS);
+					wrcodec(s->codec,
+						AC97_EXTENDED_STATUS,
+						ext_stat | (AC97_EXTSTAT_PRI |
+							    AC97_EXTSTAT_PRJ |
+							    AC97_EXTSTAT_PRK));
+				} else if (val >= 4) {
+					/* enable surround, center/lfe
+					 * channels in AC'97
+					 */
+					u16             ext_stat =
+						rdcodec(s->codec,
+							AC97_EXTENDED_STATUS);
+					ext_stat &= ~AC97_EXTSTAT_PRJ;
+					if (val == 6)
+						ext_stat &=
+							~(AC97_EXTSTAT_PRI |
+							  AC97_EXTSTAT_PRK);
+					wrcodec(s->codec,
+						AC97_EXTENDED_STATUS,
+						ext_stat);
+				}
+
+				s->dma_dac.num_channels = val;
+				if ((ret = prog_dmabuf_dac(s)))
+					return ret;
+			}
+		}
+		return put_user(val, (int *) arg);
+
+	case SNDCTL_DSP_GETFMTS:	/* Returns a mask */
+		return put_user(AFMT_S16_LE | AFMT_U8, (int *) arg);
+
+	case SNDCTL_DSP_SETFMT:	/* Selects ONE fmt */
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (val != AFMT_QUERY) {
+			if (file->f_mode & FMODE_READ) {
+				stop_adc(s);
+				if (val == AFMT_S16_LE)
+					s->dma_adc.sample_size = 16;
+				else {
+					val = AFMT_U8;
+					s->dma_adc.sample_size = 8;
+				}
+				if ((ret = prog_dmabuf_adc(s)))
+					return ret;
+			}
+			if (file->f_mode & FMODE_WRITE) {
+				stop_dac(s);
+				if (val == AFMT_S16_LE)
+					s->dma_dac.sample_size = 16;
+				else {
+					val = AFMT_U8;
+					s->dma_dac.sample_size = 8;
+				}
+				if ((ret = prog_dmabuf_dac(s)))
+					return ret;
+			}
+		} else {
+			if (file->f_mode & FMODE_READ)
+				val = (s->dma_adc.sample_size == 16) ?
+					AFMT_S16_LE : AFMT_U8;
+			else
+				val = (s->dma_dac.sample_size == 16) ?
+					AFMT_S16_LE : AFMT_U8;
+		}
+		return put_user(val, (int *) arg);
+
+	case SNDCTL_DSP_POST:
+		return 0;
+
+	case SNDCTL_DSP_GETTRIGGER:
+		val = 0;
+		spin_lock_irqsave(&s->lock, flags);
+		if (file->f_mode & FMODE_READ && !s->dma_adc.stopped)
+			val |= PCM_ENABLE_INPUT;
+		if (file->f_mode & FMODE_WRITE && !s->dma_dac.stopped)
+			val |= PCM_ENABLE_OUTPUT;
+		spin_unlock_irqrestore(&s->lock, flags);
+		return put_user(val, (int *) arg);
+
+	case SNDCTL_DSP_SETTRIGGER:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (file->f_mode & FMODE_READ) {
+			if (val & PCM_ENABLE_INPUT)
+				start_adc(s);
+			else
+				stop_adc(s);
+		}
+		if (file->f_mode & FMODE_WRITE) {
+			if (val & PCM_ENABLE_OUTPUT)
+				start_dac(s);
+			else
+				stop_dac(s);
+		}
+		return 0;
+
+	case SNDCTL_DSP_GETOSPACE:
+		if (!(file->f_mode & FMODE_WRITE))
+			return -EINVAL;
+		abinfo.fragsize = s->dma_dac.fragsize;
+		spin_lock_irqsave(&s->lock, flags);
+		count = s->dma_dac.count;
+		count -= dma_count_done(&s->dma_dac);
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count < 0)
+			count = 0;
+		abinfo.bytes = (s->dma_dac.dmasize - count) /
+			s->dma_dac.cnt_factor;
+		abinfo.fragstotal = s->dma_dac.numfrag;
+		abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
+#ifdef AU1000_VERBOSE_DEBUG
+		dbg("bytes=%d, fragments=%d", abinfo.bytes, abinfo.fragments);
+#endif
+		return copy_to_user((void *) arg, &abinfo,
+				    sizeof(abinfo)) ? -EFAULT : 0;
+
+	case SNDCTL_DSP_GETISPACE:
+		if (!(file->f_mode & FMODE_READ))
+			return -EINVAL;
+		abinfo.fragsize = s->dma_adc.fragsize;
+		spin_lock_irqsave(&s->lock, flags);
+		count = s->dma_adc.count;
+		count += dma_count_done(&s->dma_adc);
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count < 0)
+			count = 0;
+		abinfo.bytes = count / s->dma_adc.cnt_factor;
+		abinfo.fragstotal = s->dma_adc.numfrag;
+		abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
+		return copy_to_user((void *) arg, &abinfo,
+				    sizeof(abinfo)) ? -EFAULT : 0;
+
+	case SNDCTL_DSP_NONBLOCK:
+		file->f_flags |= O_NONBLOCK;
+		return 0;
+
+	case SNDCTL_DSP_GETODELAY:
+		if (!(file->f_mode & FMODE_WRITE))
+			return -EINVAL;
+		spin_lock_irqsave(&s->lock, flags);
+		count = s->dma_dac.count;
+		count -= dma_count_done(&s->dma_dac);
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count < 0)
+			count = 0;
+		count /= s->dma_dac.cnt_factor;
+		return put_user(count, (int *) arg);
+
+	case SNDCTL_DSP_GETIPTR:
+		if (!(file->f_mode & FMODE_READ))
+			return -EINVAL;
+		spin_lock_irqsave(&s->lock, flags);
+		cinfo.bytes = s->dma_adc.total_bytes;
+		count = s->dma_adc.count;
+		if (!s->dma_adc.stopped) {
+			diff = dma_count_done(&s->dma_adc);
+			count += diff;
+			cinfo.bytes += diff;
+			cinfo.ptr =  virt_to_phys(s->dma_adc.nextIn) + diff -
+				virt_to_phys(s->dma_adc.rawbuf);
+		} else
+			cinfo.ptr = virt_to_phys(s->dma_adc.nextIn) -
+				virt_to_phys(s->dma_adc.rawbuf);
+		if (s->dma_adc.mapped)
+			s->dma_adc.count &= (s->dma_adc.dma_fragsize-1);
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count < 0)
+			count = 0;
+		cinfo.blocks = count >> s->dma_adc.fragshift;
+		return copy_to_user((void *) arg, &cinfo, sizeof(cinfo));
+
+	case SNDCTL_DSP_GETOPTR:
+		if (!(file->f_mode & FMODE_READ))
+			return -EINVAL;
+		spin_lock_irqsave(&s->lock, flags);
+		cinfo.bytes = s->dma_dac.total_bytes;
+		count = s->dma_dac.count;
+		if (!s->dma_dac.stopped) {
+			diff = dma_count_done(&s->dma_dac);
+			count -= diff;
+			cinfo.bytes += diff;
+			cinfo.ptr = virt_to_phys(s->dma_dac.nextOut) + diff -
+				virt_to_phys(s->dma_dac.rawbuf);
+		} else
+			cinfo.ptr = virt_to_phys(s->dma_dac.nextOut) -
+				virt_to_phys(s->dma_dac.rawbuf);
+		if (s->dma_dac.mapped)
+			s->dma_dac.count &= (s->dma_dac.dma_fragsize-1);
+		spin_unlock_irqrestore(&s->lock, flags);
+		if (count < 0)
+			count = 0;
+		cinfo.blocks = count >> s->dma_dac.fragshift;
+		return copy_to_user((void *) arg, &cinfo, sizeof(cinfo));
+
+	case SNDCTL_DSP_GETBLKSIZE:
+		if (file->f_mode & FMODE_WRITE)
+			return put_user(s->dma_dac.fragsize, (int *) arg);
+		else
+			return put_user(s->dma_adc.fragsize, (int *) arg);
+
+	case SNDCTL_DSP_SETFRAGMENT:
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (file->f_mode & FMODE_READ) {
+			stop_adc(s);
+			s->dma_adc.ossfragshift = val & 0xffff;
+			s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
+			if (s->dma_adc.ossfragshift < 4)
+				s->dma_adc.ossfragshift = 4;
+			if (s->dma_adc.ossfragshift > 15)
+				s->dma_adc.ossfragshift = 15;
+			if (s->dma_adc.ossmaxfrags < 4)
+				s->dma_adc.ossmaxfrags = 4;
+			if ((ret = prog_dmabuf_adc(s)))
+				return ret;
+		}
+		if (file->f_mode & FMODE_WRITE) {
+			stop_dac(s);
+			s->dma_dac.ossfragshift = val & 0xffff;
+			s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
+			if (s->dma_dac.ossfragshift < 4)
+				s->dma_dac.ossfragshift = 4;
+			if (s->dma_dac.ossfragshift > 15)
+				s->dma_dac.ossfragshift = 15;
+			if (s->dma_dac.ossmaxfrags < 4)
+				s->dma_dac.ossmaxfrags = 4;
+			if ((ret = prog_dmabuf_dac(s)))
+				return ret;
+		}
+		return 0;
+
+	case SNDCTL_DSP_SUBDIVIDE:
+		if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
+		    (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
+			return -EINVAL;
+		if (get_user(val, (int *) arg))
+			return -EFAULT;
+		if (val != 1 && val != 2 && val != 4)
+			return -EINVAL;
+		if (file->f_mode & FMODE_READ) {
+			stop_adc(s);
+			s->dma_adc.subdivision = val;
+			if ((ret = prog_dmabuf_adc(s)))
+				return ret;
+		}
+		if (file->f_mode & FMODE_WRITE) {
+			stop_dac(s);
+			s->dma_dac.subdivision = val;
+			if ((ret = prog_dmabuf_dac(s)))
+				return ret;
+		}
+		return 0;
+
+	case SOUND_PCM_READ_RATE:
+		return put_user((file->f_mode & FMODE_READ) ?
+				s->dma_adc.sample_rate :
+				s->dma_dac.sample_rate,
+				(int *)arg);
+
+	case SOUND_PCM_READ_CHANNELS:
+		if (file->f_mode & FMODE_READ)
+			return put_user(s->dma_adc.num_channels, (int *)arg);
+		else
+			return put_user(s->dma_dac.num_channels, (int *)arg);
+
+	case SOUND_PCM_READ_BITS:
+		if (file->f_mode & FMODE_READ)
+			return put_user(s->dma_adc.sample_size, (int *)arg);
+		else
+			return put_user(s->dma_dac.sample_size, (int *)arg);
+
+	case SOUND_PCM_WRITE_FILTER:
+	case SNDCTL_DSP_SETSYNCRO:
+	case SOUND_PCM_READ_FILTER:
+		return -EINVAL;
+	}
+
+	return mixdev_ioctl(s->codec, cmd, arg);
+}
+
+
+static int
+au1550_open(struct inode *inode, struct file *file)
+{
+	int             minor = MINOR(inode->i_rdev);
+	DECLARE_WAITQUEUE(wait, current);
+	struct au1550_state *s = &au1550_state;
+	int             ret;
+
+#ifdef AU1000_VERBOSE_DEBUG
+	if (file->f_flags & O_NONBLOCK)
+		dbg(__FUNCTION__ ": non-blocking");
+	else
+		dbg(__FUNCTION__ ": blocking");
+#endif
+	
+	file->private_data = s;
+	/* wait for device to become free */
+	down(&s->open_sem);
+	while (s->open_mode & file->f_mode) {
+		if (file->f_flags & O_NONBLOCK) {
+			up(&s->open_sem);
+			return -EBUSY;
+		}
+		add_wait_queue(&s->open_wait, &wait);
+		__set_current_state(TASK_INTERRUPTIBLE);
+		up(&s->open_sem);
+		schedule();
+		remove_wait_queue(&s->open_wait, &wait);
+		set_current_state(TASK_RUNNING);
+		if (signal_pending(current))
+			return -ERESTARTSYS;
+		down(&s->open_sem);
+	}
+
+	stop_dac(s);
+	stop_adc(s);
+
+	if (file->f_mode & FMODE_READ) {
+		s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags =
+			s->dma_adc.subdivision = s->dma_adc.total_bytes = 0;
+		s->dma_adc.num_channels = 1;
+		s->dma_adc.sample_size = 8;
+		set_adc_rate(s, 8000);
+		if ((minor & 0xf) == SND_DEV_DSP16)
+			s->dma_adc.sample_size = 16;
+	}
+
+	if (file->f_mode & FMODE_WRITE) {
+		s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags =
+			s->dma_dac.subdivision = s->dma_dac.total_bytes = 0;
+		s->dma_dac.num_channels = 1;
+		s->dma_dac.sample_size = 8;
+		set_dac_rate(s, 8000);
+		if ((minor & 0xf) == SND_DEV_DSP16)
+			s->dma_dac.sample_size = 16;
+	}
+
+	if (file->f_mode & FMODE_READ) {
+		if ((ret = prog_dmabuf_adc(s)))
+			return ret;
+	}
+	if (file->f_mode & FMODE_WRITE) {
+		if ((ret = prog_dmabuf_dac(s)))
+			return ret;
+	}
+
+	s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
+	up(&s->open_sem);
+	init_MUTEX(&s->sem);
+	return 0;
+}
+
+static int
+au1550_release(struct inode *inode, struct file *file)
+{
+	struct au1550_state *s = (struct au1550_state *)file->private_data;
+
+	lock_kernel();
+	
+	if (file->f_mode & FMODE_WRITE) {
+		unlock_kernel();
+		drain_dac(s, file->f_flags & O_NONBLOCK);
+		lock_kernel();
+	}
+
+	down(&s->open_sem);
+	if (file->f_mode & FMODE_WRITE) {
+		stop_dac(s);
+		kfree(s->dma_dac.rawbuf);
+		s->dma_dac.rawbuf = NULL;
+	}
+	if (file->f_mode & FMODE_READ) {
+		stop_adc(s);
+		kfree(s->dma_adc.rawbuf);
+		s->dma_adc.rawbuf = NULL;
+	}
+	s->open_mode &= ((~file->f_mode) & (FMODE_READ|FMODE_WRITE));
+	up(&s->open_sem);
+	wake_up(&s->open_wait);
+	unlock_kernel();
+	return 0;
+}
+
+static /*const */ struct file_operations au1550_audio_fops = {
+	owner:		THIS_MODULE,
+	llseek:		au1550_llseek,
+	read:		au1550_read,
+	write:		au1550_write,
+	poll:		au1550_poll,
+	ioctl:		au1550_ioctl,
+	mmap:		au1550_mmap,
+	open:		au1550_open,
+	release:	au1550_release,
+};
+
+MODULE_AUTHOR("Advanced Micro Devices (AMD), dan@embeddededge.com");
+MODULE_DESCRIPTION("Au1550 Audio Driver");
+
+static int __devinit
+au1550_probe(void)
+{
+	struct au1550_state *s = &au1550_state;
+	int             val;
+#ifdef AU1550_DEBUG
+	char            proc_str[80];
+#endif
+
+	memset(s, 0, sizeof(struct au1550_state));
+
+	init_waitqueue_head(&s->dma_adc.wait);
+	init_waitqueue_head(&s->dma_dac.wait);
+	init_waitqueue_head(&s->open_wait);
+	init_MUTEX(&s->open_sem);
+	spin_lock_init(&s->lock);
+
+	s->codec = ac97_alloc_codec();
+	if(s->codec == NULL) {
+		err("Out of memory");
+		return -1;
+	}
+	s->codec->private_data = s;
+	s->codec->id = 0;
+	s->codec->codec_read = rdcodec;
+	s->codec->codec_write = wrcodec;
+	s->codec->codec_wait = waitcodec;
+
+	if (!request_region(PHYSADDR(AC97_PSC_SEL),
+			    0x30, AU1550_MODULE_NAME)) {
+		err("AC'97 ports in use");
+	}
+
+	/* Allocate the DMA Channels
+	*/
+	if ((s->dma_dac.dmanr = au1xxx_dbdma_chan_alloc(DBDMA_MEM_CHAN,
+	    DBDMA_AC97_TX_CHAN, dac_dma_interrupt, (void *)s)) == 0) {
+		err("Can't get DAC DMA");
+		goto err_dma1;
+	}
+	au1xxx_dbdma_set_devwidth(s->dma_dac.dmanr, 16);
+	if (au1xxx_dbdma_ring_alloc(s->dma_dac.dmanr,
+					NUM_DBDMA_DESCRIPTORS) == 0) {
+		err("Can't get DAC DMA descriptors");
+		goto err_dma1;
+	}
+
+	if ((s->dma_adc.dmanr = au1xxx_dbdma_chan_alloc(DBDMA_AC97_RX_CHAN,
+	    DBDMA_MEM_CHAN, adc_dma_interrupt, (void *)s)) == 0) {
+		err("Can't get ADC DMA");
+		goto err_dma2;
+	}
+	au1xxx_dbdma_set_devwidth(s->dma_adc.dmanr, 16);
+	if (au1xxx_dbdma_ring_alloc(s->dma_adc.dmanr,
+					NUM_DBDMA_DESCRIPTORS) == 0) {
+		err("Can't get ADC DMA descriptors");
+		goto err_dma2;
+	}
+
+	info("DAC: DMA%d, ADC: DMA%d", DBDMA_AC97_TX_CHAN, DBDMA_AC97_RX_CHAN);
+
+	/* register devices */
+
+	if ((s->dev_audio = register_sound_dsp(&au1550_audio_fops, -1)) < 0)
+		goto err_dev1;
+	if ((s->codec->dev_mixer =
+	     register_sound_mixer(&au1550_mixer_fops, -1)) < 0)
+		goto err_dev2;
+
+#ifdef AU1550_DEBUG
+	/* intialize the debug proc device */
+	s->ps = create_proc_read_entry(AU1000_MODULE_NAME, 0, NULL,
+				       proc_au1550_dump, NULL);
+#endif /* AU1550_DEBUG */
+
+	/* The GPIO for the appropriate PSC was configured by the
+	 * board specific start up.
+	 *
+	 * configure PSC for AC'97
+	 */
+	au_writel(0, AC97_PSC_CTRL);	/* Disable PSC */
+	au_sync();
+	au_writel((PSC_SEL_CLK_SERCLK | PSC_SEL_PS_AC97MODE), AC97_PSC_SEL);
+	au_sync();
+
+	/* cold reset the AC'97
+	*/
+	au_writel(PSC_AC97RST_RST, PSC_AC97RST);
+	au_sync();
+	au1550_delay(10);
+	au_writel(0, PSC_AC97RST);
+	au_sync();
+
+	/* need to delay around 500msec(bleech) to give
+	   some CODECs enough time to wakeup */
+	au1550_delay(500);
+
+	/* warm reset the AC'97 to start the bitclk
+	*/
+	au_writel(PSC_AC97RST_SNC, PSC_AC97RST);
+	au_sync();
+	udelay(100);
+	au_writel(0, PSC_AC97RST);
+	au_sync();
+
+	/* Enable PSC
+	*/
+	au_writel(PSC_CTRL_ENABLE, AC97_PSC_CTRL);
+	au_sync();
+
+	/* Wait for PSC ready.
+	*/
+	do {
+		val = readl(PSC_AC97STAT);
+		au_sync();
+	} while ((val & PSC_AC97STAT_SR) == 0);
+
+	/* Configure AC97 controller.
+	 * Deep FIFO, 16-bit sample, DMA, make sure DMA matches fifo size.
+	 */
+	val = PSC_AC97CFG_SET_LEN(16);
+	val |= PSC_AC97CFG_RT_FIFO8 | PSC_AC97CFG_TT_FIFO8;
+
+	/* Enable device so we can at least
+	 * talk over the AC-link.
+	 */
+	au_writel(val, PSC_AC97CFG);
+	au_writel(PSC_AC97MSK_ALLMASK, PSC_AC97MSK);
+	au_sync();
+	val |= PSC_AC97CFG_DE_ENABLE;
+	au_writel(val, PSC_AC97CFG);
+	au_sync();
+
+	/* Wait for Device ready.
+	*/
+	do {
+		val = readl(PSC_AC97STAT);
+		au_sync();
+	} while ((val & PSC_AC97STAT_DR) == 0);
+
+	/* codec init */
+	if (!ac97_probe_codec(s->codec))
+		goto err_dev3;
+
+	s->codec_base_caps = rdcodec(s->codec, AC97_RESET);
+	s->codec_ext_caps = rdcodec(s->codec, AC97_EXTENDED_ID);
+	info("AC'97 Base/Extended ID = %04x/%04x",
+	     s->codec_base_caps, s->codec_ext_caps);
+
+	if (!(s->codec_ext_caps & AC97_EXTID_VRA)) {
+		/* codec does not support VRA
+		*/
+		s->no_vra = 1;
+	} else if (!vra) {
+		/* Boot option says disable VRA
+		*/
+		u16 ac97_extstat = rdcodec(s->codec, AC97_EXTENDED_STATUS);
+		wrcodec(s->codec, AC97_EXTENDED_STATUS,
+			ac97_extstat & ~AC97_EXTSTAT_VRA);
+		s->no_vra = 1;
+	}
+	if (s->no_vra)
+		info("no VRA, interpolating and decimating");
+
+	/* set mic to be the recording source */
+	val = SOUND_MASK_MIC;
+	mixdev_ioctl(s->codec, SOUND_MIXER_WRITE_RECSRC,
+		     (unsigned long) &val);
+#ifdef AU1550_DEBUG
+	sprintf(proc_str, "driver/%s/%d/ac97", AU1550_MODULE_NAME,
+		s->codec->id);
+	s->ac97_ps = create_proc_read_entry (proc_str, 0, NULL,
+					     ac97_read_proc, &s->codec);
+#endif
+
+	return 0;
+
+ err_dev3:
+	unregister_sound_mixer(s->codec->dev_mixer);
+ err_dev2:
+	unregister_sound_dsp(s->dev_audio);
+ err_dev1:
+	au1xxx_dbdma_chan_free(s->dma_adc.dmanr);
+ err_dma2:
+	au1xxx_dbdma_chan_free(s->dma_dac.dmanr);
+ err_dma1:
+	release_region(PHYSADDR(AC97_PSC_SEL), 0x30);
+
+	ac97_release_codec(s->codec);
+	return -1;
+}
+
+static void __devinit
+au1550_remove(void)
+{
+	struct au1550_state *s = &au1550_state;
+
+	if (!s)
+		return;
+#ifdef AU1550_DEBUG
+	if (s->ps)
+		remove_proc_entry(AU1000_MODULE_NAME, NULL);
+#endif /* AU1000_DEBUG */
+	synchronize_irq();
+	au1xxx_dbdma_chan_free(s->dma_adc.dmanr);
+	au1xxx_dbdma_chan_free(s->dma_dac.dmanr);
+	release_region(PHYSADDR(AC97_PSC_SEL), 0x30);
+	unregister_sound_dsp(s->dev_audio);
+	unregister_sound_mixer(s->codec->dev_mixer);
+	ac97_release_codec(s->codec);
+}
+
+static int __init
+init_au1550(void)
+{
+	return au1550_probe();
+}
+
+static void __exit
+cleanup_au1550(void)
+{
+	au1550_remove();
+}
+
+module_init(init_au1550);
+module_exit(cleanup_au1550);
+
+#ifndef MODULE
+
+static int __init
+au1550_setup(char *options)
+{
+	char           *this_opt;
+
+	if (!options || !*options)
+		return 0;
+
+	for(this_opt=strtok(options, ",");
+	    this_opt; this_opt=strtok(NULL, ",")) {
+		if (!strncmp(this_opt, "vra", 3)) {
+			vra = 1;
+		}
+	}
+
+	return 1;
+}
+
+__setup("au1550_audio=", au1550_setup);
+
+#endif /* MODULE */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/sound/swarm_cs4297a.c linux-2.4.29-pre3/drivers/sound/swarm_cs4297a.c
--- linux-2.4.28/drivers/sound/swarm_cs4297a.c	2003-08-25 11:44:42.000000000 +0000
+++ linux-2.4.29-pre3/drivers/sound/swarm_cs4297a.c	2004-12-22 16:07:54.584878392 +0000
@@ -11,6 +11,7 @@
 *            -- adapted from cs4281 PCI driver for cs4297a on
 *               BCM1250 Synchronous Serial interface
 *               (Kip Walker, Broadcom Corp.)
+*      Copyright (C) 2004  Maciej W. Rozycki
 *
 *      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
@@ -71,14 +72,16 @@
 #include <linux/ac97_codec.h>
 #include <linux/pci.h>
 #include <linux/bitops.h>
-#include <asm/io.h>
-#include <asm/dma.h>
 #include <linux/init.h>
 #include <linux/poll.h>
 #include <linux/smp_lock.h>
 #include <linux/wrapper.h>
-#include <asm/uaccess.h>
+
+#include <asm/byteorder.h>
+#include <asm/dma.h>
 #include <asm/hardirq.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
 
 #include <asm/sibyte/sb1250_regs.h>
 #include <asm/sibyte/sb1250_int.h>
@@ -758,7 +761,7 @@ static int serdma_reg_access(struct cs42
 
                 descr = &d->descrtab[swptr];
                 data_p = &d->dma_buf[swptr * 4];
-                *data_p = data;
+		*data_p = cpu_to_be64(data);
                 out64(1, SS_CSR(R_SER_DMA_DSCR_COUNT_TX));
                 CS_DBGOUT(CS_DESCR, 4,
                           printk(KERN_INFO "cs4297a: add_tx  %p (%x -> %x)\n",
@@ -950,7 +953,7 @@ static void cs4297a_update_ptr(struct cs
                         s_ptr = (u32 *)&(d->dma_buf[d->swptr*4]);
                         descr = &d->descrtab[d->swptr];
                         while (diff2--) {
-                                u64 data = *(u64 *)s_ptr;
+				u64 data = be64_to_cpu(*(u64 *)s_ptr);
                                 u64 descr_a;
                                 u16 left, right;
                                 descr_a = descr->descr_a;
@@ -977,10 +980,11 @@ static void cs4297a_update_ptr(struct cs
                                         continue;
                                 }
                                 good_diff++;
-                                left = ((s_ptr[1] & 0xff) << 8) | ((s_ptr[2] >> 24) & 0xff);
-                                right = (s_ptr[2] >> 4) & 0xffff;
-                                *d->sb_hwptr++ = left;
-                                *d->sb_hwptr++ = right;
+				left = ((be32_to_cpu(s_ptr[1]) & 0xff) << 8) |
+				       ((be32_to_cpu(s_ptr[2]) >> 24) & 0xff);
+				right = (be32_to_cpu(s_ptr[2]) >> 4) & 0xffff;
+				*d->sb_hwptr++ = cpu_to_be16(left);
+				*d->sb_hwptr++ = cpu_to_be16(right);
                                 if (d->sb_hwptr == d->sb_end)
                                         d->sb_hwptr = d->sample_buf;
                                 descr++;
@@ -1025,7 +1029,7 @@ static void cs4297a_update_ptr(struct cs
                            here because of an interrupt, so there must
                            be a buffer to process. */
                         do {
-                                data = *data_p;
+				data = be64_to_cpu(*data_p);
                                 if ((descr->descr_a & M_DMA_DSCRA_A_ADDR) != PHYSADDR((long)data_p)) {
                                         printk(KERN_ERR "cs4297a: RX Bad address %d (%llx %lx)\n", d->swptr,
                                                (long long)(descr->descr_a & M_DMA_DSCRA_A_ADDR),
@@ -1804,7 +1808,6 @@ static ssize_t cs4297a_write(struct file
                 u32 *s_tmpl;
                 u32 *t_tmpl;
                 u32 left, right;
-                /* XXXKW check system endian here ... */
                 int swap = (s->prop_dac.fmt == AFMT_S16_LE) || (s->prop_dac.fmt == AFMT_U16_LE);
                 
                 /* XXXXXX this is broken for BLOAT_FACTOR */
@@ -1845,21 +1848,21 @@ static ssize_t cs4297a_write(struct file
 
                 /* XXXKW assuming 16-bit stereo! */
                 do {
-                        t_tmpl[0] = 0x98000000;
-                        left = s_tmpl[0] >> 16;
-                        if (left & 0x8000)
-                                left |= 0xf0000;
-                        right = s_tmpl[0] & 0xffff;
-                        if (right & 0x8000)
-                                right |= 0xf0000;
-                        if (swap) {
-                          t_tmpl[1] = left & 0xff;
-                          t_tmpl[2] = ((left & 0xff00) << 16) | ((right & 0xff) << 12) |
-                              ((right & 0xff00) >> 4);
-                        } else {
-                          t_tmpl[1] = left >> 8;
-                          t_tmpl[2] = ((left & 0xff) << 24) | (right << 4);
-                        }
+			u32 tmp;
+
+			t_tmpl[0] = cpu_to_be32(0x98000000);
+
+			tmp = be32_to_cpu(s_tmpl[0]);
+			left = tmp & 0xffff;
+			right = tmp >> 16;
+			if (swap) {
+				left = swab16(left);
+				right = swab16(right);
+			}
+			t_tmpl[1] = cpu_to_be32(left >> 8);
+			t_tmpl[2] = cpu_to_be32(((left & 0xff) << 24) |
+						(right << 4));
+
                         s_tmpl++;
                         t_tmpl += 8;
                         copy_cnt -= 4;
@@ -1867,7 +1870,8 @@ static ssize_t cs4297a_write(struct file
 
                 /* Mux in any pending read/write accesses */
                 if (s->reg_request) {
-                        *(u64 *)(d->dma_buf + (swptr * 4)) |= s->reg_request;
+			*(u64 *)(d->dma_buf + (swptr * 4)) |=
+				cpu_to_be64(s->reg_request);
                         s->reg_request = 0;
                         wake_up(&s->dma_dac.reg_wait);
                 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/sound/via82cxxx_audio.c linux-2.4.29-pre3/drivers/sound/via82cxxx_audio.c
--- linux-2.4.28/drivers/sound/via82cxxx_audio.c	2003-08-25 11:44:42.000000000 +0000
+++ linux-2.4.29-pre3/drivers/sound/via82cxxx_audio.c	2004-12-22 16:06:14.617075808 +0000
@@ -63,11 +63,6 @@
         }
 #endif
 
-#if defined(CONFIG_PROC_FS) && \
-    defined(CONFIG_SOUND_VIA82CXXX_PROCFS)
-#define VIA_PROC_FS 1
-#endif
-
 #define VIA_SUPPORT_MMAP 1 /* buggy, for now... */
 
 #define MAX_CARDS	1
@@ -367,7 +362,7 @@ static void via_chan_clear (struct via_i
 static void via_chan_pcm_fmt (struct via_channel *chan, int reset);
 static void via_chan_buffer_free (struct via_info *card, struct via_channel *chan);
 
-#ifdef VIA_PROC_FS
+#ifdef CONFIG_PROC_FS
 static int via_init_proc (void);
 static void via_cleanup_proc (void);
 static int via_card_init_proc (struct via_info *card);
@@ -3655,7 +3650,7 @@ EXPORT_NO_SYMBOLS;
 
 
 
-#ifdef VIA_PROC_FS
+#ifdef CONFIG_PROC_FS
 
 /****************************************************************
  *
@@ -3831,4 +3826,4 @@ static void via_card_cleanup_proc (struc
 	DPRINTK ("EXIT\n");
 }
 
-#endif /* VIA_PROC_FS */
+#endif /* CONFIG_PROC_FS */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/tc/zs.c linux-2.4.29-pre3/drivers/tc/zs.c
--- linux-2.4.28/drivers/tc/zs.c	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-pre3/drivers/tc/zs.c	2004-12-22 16:07:31.182436104 +0000
@@ -695,10 +695,7 @@ static void do_softint(void *private_)
 		return;
 
 	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup)(tty);
-		wake_up_interruptible(&tty->write_wait);
+		tty_wakeup(tty);
 	}
 }
 
@@ -1020,10 +1017,7 @@ static void rs_flush_buffer(struct tty_s
 	cli();
 	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
 	sti();
-	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
+	tty_wakeup(tty);
 }
 
 /*
@@ -1429,8 +1423,7 @@ static void rs_close(struct tty_struct *
 	shutdown(info);
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	tty_ldisc_flush(tty);
 	tty->closing = 0;
 	info->event = 0;
 	info->tty = 0;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/usb/acm.c linux-2.4.29-pre3/drivers/usb/acm.c
--- linux-2.4.28/drivers/usb/acm.c	2003-11-28 18:26:20.000000000 +0000
+++ linux-2.4.29-pre3/drivers/usb/acm.c	2004-12-22 16:07:05.982267112 +0000
@@ -285,10 +285,7 @@ static void acm_softint(void *private)
 
 	if (!ACM_READY(acm)) return;
 
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
-
-	wake_up_interruptible(&tty->write_wait);
+	tty_wakeup(tty);
 }
 
 /*
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/usb/bluetooth.c linux-2.4.29-pre3/drivers/usb/bluetooth.c
--- linux-2.4.28/drivers/usb/bluetooth.c	2003-11-28 18:26:20.000000000 +0000
+++ linux-2.4.29-pre3/drivers/usb/bluetooth.c	2004-12-22 16:05:58.067591712 +0000
@@ -1017,6 +1017,7 @@ static void bluetooth_softint(void *priv
 {
 	struct usb_bluetooth *bluetooth = get_usb_bluetooth ((struct usb_bluetooth *)private, __FUNCTION__);
 	struct tty_struct *tty;
+	struct tty_ldisc *ld;
 
 	dbg("%s", __FUNCTION__);
 
@@ -1025,9 +1026,15 @@ static void bluetooth_softint(void *priv
 	}
 
 	tty = bluetooth->tty;
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) {
-		dbg("%s - write wakeup call.", __FUNCTION__);
-		(tty->ldisc.write_wakeup)(tty);
+	if (tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) {
+		ld = tty_ldisc_ref(tty);
+		if(ld) {
+			if(ld->write_wakeup) {
+				ld->write_wakeup(tty);
+				dbg("%s - write wakeup call.", __FUNCTION__);
+			}
+			tty_ldisc_deref(tty);
+		}
 	}
 
 	wake_up_interruptible(&tty->write_wait);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/usb/gadget/Config.in linux-2.4.29-pre3/drivers/usb/gadget/Config.in
--- linux-2.4.28/drivers/usb/gadget/Config.in	2004-08-07 23:26:05.000000000 +0000
+++ linux-2.4.29-pre3/drivers/usb/gadget/Config.in	2004-12-22 16:06:39.365313504 +0000
@@ -52,9 +52,9 @@ if [ "$CONFIG_USB_GADGET" = "y" -o "$CON
   comment 'USB Gadget Drivers'
 
   dep_tristate '  Gadget Zero (DEVELOPMENT)' CONFIG_USB_ZERO $CONFIG_USB_GADGET_CONTROLLER
-  dep_tristate '  Ethernet Gadget (EXPERIMENTAL)' CONFIG_USB_ETH $CONFIG_USB_GADGET_CONTROLLER $CONFIG_NET
+  dep_tristate '  Ethernet Gadget' CONFIG_USB_ETH $CONFIG_USB_GADGET_CONTROLLER $CONFIG_NET
   if [ "$CONFIG_USB_ETH" = "y" -o "$CONFIG_USB_ETH" = "m" ] ; then
-    bool       '    RNDIS support (EXPERIMENTAL)' CONFIG_USB_ETH_RNDIS
+    dep_bool       '    RNDIS support (EXPERIMENTAL)' CONFIG_USB_ETH_RNDIS $CONFIG_EXPERIMENTAL
   fi
   dep_tristate '  File-backed Storage Gadget (DEVELOPMENT)' CONFIG_USB_FILE_STORAGE $CONFIG_USB_GADGET_CONTROLLER
   dep_mbool '    File-backed Storage Gadget test mode' CONFIG_USB_FILE_STORAGE_TEST $CONFIG_USB_FILE_STORAGE
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/usb/gadget/epautoconf.c linux-2.4.29-pre3/drivers/usb/gadget/epautoconf.c
--- linux-2.4.28/drivers/usb/gadget/epautoconf.c	2004-08-07 23:26:05.000000000 +0000
+++ linux-2.4.29-pre3/drivers/usb/gadget/epautoconf.c	2004-12-22 16:06:55.506859616 +0000
@@ -56,6 +56,9 @@ static __initdata unsigned in_epnum;
  *
  * Type suffixes are "-bulk", "-iso", or "-int".  Numbers are decimal.
  * Less common restrictions are implied by gadget_is_*().
+ *
+ * NOTE:  each endpoint is unidirectional, as specified by its USB
+ * descriptor.
  */
 static int __init
 ep_matches (
@@ -193,7 +196,7 @@ find_ep (struct usb_gadget *gadget, cons
 		if (0 == strcmp (ep->name, name))
 			return ep;
 	}
-	return 0;
+	return NULL;
 }
 
 /**
@@ -281,7 +284,7 @@ struct usb_ep * __init usb_ep_autoconfig
 	}
 
 	/* Fail */
-	return 0;
+	return NULL;
 }
 
 /**
@@ -298,7 +301,7 @@ void __init usb_ep_autoconfig_reset (str
 	struct usb_ep	*ep;
 
 	list_for_each_entry (ep, &gadget->ep_list, ep_list) {
-		ep->driver_data = 0;
+		ep->driver_data = NULL;
 	}
 #ifdef	MANY_ENDPOINTS
 	in_epnum = 0;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/usb/gadget/ether.c linux-2.4.29-pre3/drivers/usb/gadget/ether.c
--- linux-2.4.28/drivers/usb/gadget/ether.c	2004-08-07 23:26:05.000000000 +0000
+++ linux-2.4.29-pre3/drivers/usb/gadget/ether.c	2004-12-22 16:05:32.368498568 +0000
@@ -62,6 +62,7 @@
 
 /*
  * Ethernet gadget driver -- with CDC and non-CDC options
+ * Builds on hardware support for a full duplex link.
  *
  * CDC Ethernet is the standard USB solution for sending Ethernet frames
  * using USB.  Real hardware tends to use the same framing protocol but look
@@ -82,7 +83,7 @@
  */
 
 #define DRIVER_DESC		"Ethernet Gadget"
-#define DRIVER_VERSION		"St Patrick's Day 2004"
+#define DRIVER_VERSION		"Equinox 2004"
 
 static const char shortname [] = "ether";
 static const char driver_desc [] = DRIVER_DESC;
@@ -239,6 +240,10 @@ MODULE_PARM_DESC(host_addr, "Host Ethern
 #define	DEV_CONFIG_CDC
 #endif
 
+#ifdef CONFIG_USB_GADGET_LH7A40X
+#define DEV_CONFIG_CDC
+#endif
+
 #ifdef CONFIG_USB_GADGET_MQ11XX
 #define	DEV_CONFIG_CDC
 #endif
@@ -247,6 +252,14 @@ MODULE_PARM_DESC(host_addr, "Host Ethern
 #define	DEV_CONFIG_CDC
 #endif
 
+#ifdef CONFIG_USB_GADGET_N9604
+#define	DEV_CONFIG_CDC
+#endif
+
+#ifdef CONFIG_USB_GADGET_PXA27X
+#define DEV_CONFIG_CDC
+#endif
+
 
 /* For CDC-incapable hardware, choose the simple cdc subset.
  * Anything that talks bulk (without notable bugs) can do this.
@@ -355,6 +368,9 @@ module_param (qmult, uint, 0);
  *
  * NOTE:  Controllers like superh_udc should probably be able to use
  * an RNDIS-only configuration.
+ *
+ * FIXME define some higher-powered configurations to make it easier
+ * to recharge batteries ...
  */
 
 #define DEV_CONFIG_VALUE	1	/* cdc or subset */
@@ -378,6 +394,14 @@ device_desc = {
 	.bNumConfigurations =	1,
 };
 
+static struct usb_otg_descriptor
+otg_descriptor = {
+	.bLength =		sizeof otg_descriptor,
+	.bDescriptorType =	USB_DT_OTG,
+
+	.bmAttributes =		USB_OTG_SRP,
+};
+
 static struct usb_config_descriptor
 eth_config = {
 	.bLength =		sizeof eth_config,
@@ -388,11 +412,11 @@ eth_config = {
 	.bConfigurationValue =	DEV_CONFIG_VALUE,
 	.iConfiguration =	STRING_CDC,
 	.bmAttributes =		USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
-	.bMaxPower =		1,
+	.bMaxPower =		50,
 };
 
 #ifdef	CONFIG_USB_ETH_RNDIS
-static const struct usb_config_descriptor 
+static struct usb_config_descriptor 
 rndis_config = {
 	.bLength =              sizeof rndis_config,
 	.bDescriptorType =      USB_DT_CONFIG,
@@ -402,7 +426,7 @@ rndis_config = {
 	.bConfigurationValue =  DEV_RNDIS_CONFIG_VALUE,
 	.iConfiguration =       STRING_RNDIS,
 	.bmAttributes =		USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
-	.bMaxPower =            1,
+	.bMaxPower =            50,
 };
 #endif
 
@@ -688,7 +712,8 @@ fs_sink_desc = {
 	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
 };
 
-static const struct usb_descriptor_header *fs_eth_function [10] = {
+static const struct usb_descriptor_header *fs_eth_function [11] = {
+	(struct usb_descriptor_header *) &otg_descriptor,
 #ifdef DEV_CONFIG_CDC
 	/* "cdc" mode descriptors */
 	(struct usb_descriptor_header *) &control_intf,
@@ -702,24 +727,25 @@ static const struct usb_descriptor_heade
 	(struct usb_descriptor_header *) &data_intf,
 	(struct usb_descriptor_header *) &fs_source_desc,
 	(struct usb_descriptor_header *) &fs_sink_desc,
-	0,
+	NULL,
 #endif /* DEV_CONFIG_CDC */
 };
 
 static inline void __init fs_subset_descriptors(void)
 {
 #ifdef DEV_CONFIG_SUBSET
-	fs_eth_function[0] = (struct usb_descriptor_header *) &subset_data_intf;
-	fs_eth_function[1] = (struct usb_descriptor_header *) &fs_source_desc;
-	fs_eth_function[2] = (struct usb_descriptor_header *) &fs_sink_desc;
-	fs_eth_function[3] = 0;
+	fs_eth_function[1] = (struct usb_descriptor_header *) &subset_data_intf;
+	fs_eth_function[2] = (struct usb_descriptor_header *) &fs_source_desc;
+	fs_eth_function[3] = (struct usb_descriptor_header *) &fs_sink_desc;
+	fs_eth_function[4] = NULL;
 #else
-	fs_eth_function[0] = 0;
+	fs_eth_function[1] = NULL;
 #endif
 }
 
 #ifdef	CONFIG_USB_ETH_RNDIS
 static const struct usb_descriptor_header *fs_rndis_function [] = {
+	(struct usb_descriptor_header *) &otg_descriptor,
 	/* control interface matches ACM, not Ethernet */
 	(struct usb_descriptor_header *) &rndis_control_intf,
 	(struct usb_descriptor_header *) &header_desc,
@@ -731,7 +757,7 @@ static const struct usb_descriptor_heade
 	(struct usb_descriptor_header *) &rndis_data_intf,
 	(struct usb_descriptor_header *) &fs_source_desc,
 	(struct usb_descriptor_header *) &fs_sink_desc,
-	0,
+	NULL,
 };
 #endif
 
@@ -783,7 +809,8 @@ dev_qualifier = {
 	.bNumConfigurations =	1,
 };
 
-static const struct usb_descriptor_header *hs_eth_function [10] = {
+static const struct usb_descriptor_header *hs_eth_function [11] = {
+	(struct usb_descriptor_header *) &otg_descriptor,
 #ifdef DEV_CONFIG_CDC
 	/* "cdc" mode descriptors */
 	(struct usb_descriptor_header *) &control_intf,
@@ -797,24 +824,25 @@ static const struct usb_descriptor_heade
 	(struct usb_descriptor_header *) &data_intf,
 	(struct usb_descriptor_header *) &hs_source_desc,
 	(struct usb_descriptor_header *) &hs_sink_desc,
-	0,
+	NULL,
 #endif /* DEV_CONFIG_CDC */
 };
 
 static inline void __init hs_subset_descriptors(void)
 {
 #ifdef DEV_CONFIG_SUBSET
-	hs_eth_function[0] = (struct usb_descriptor_header *) &subset_data_intf;
-	hs_eth_function[1] = (struct usb_descriptor_header *) &fs_source_desc;
-	hs_eth_function[2] = (struct usb_descriptor_header *) &fs_sink_desc;
-	hs_eth_function[3] = 0;
+	hs_eth_function[1] = (struct usb_descriptor_header *) &subset_data_intf;
+	hs_eth_function[2] = (struct usb_descriptor_header *) &fs_source_desc;
+	hs_eth_function[3] = (struct usb_descriptor_header *) &fs_sink_desc;
+	hs_eth_function[4] = NULL;
 #else
-	hs_eth_function[0] = 0;
+	hs_eth_function[1] = NULL;
 #endif
 }
 
 #ifdef	CONFIG_USB_ETH_RNDIS
 static const struct usb_descriptor_header *hs_rndis_function [] = {
+	(struct usb_descriptor_header *) &otg_descriptor,
 	/* control interface matches ACM, not Ethernet */
 	(struct usb_descriptor_header *) &rndis_control_intf,
 	(struct usb_descriptor_header *) &header_desc,
@@ -826,7 +854,7 @@ static const struct usb_descriptor_heade
 	(struct usb_descriptor_header *) &rndis_data_intf,
 	(struct usb_descriptor_header *) &hs_source_desc,
 	(struct usb_descriptor_header *) &hs_sink_desc,
-	0,
+	NULL,
 };
 #endif
 
@@ -849,7 +877,7 @@ static inline void __init hs_subset_desc
 
 /* descriptors that are built on-demand */
 
-static char				manufacturer [40];
+static char				manufacturer [50];
 static char				product_desc [40] = DRIVER_DESC;
 
 #ifdef	DEV_CONFIG_CDC
@@ -857,7 +885,7 @@ static char				product_desc [40] = DRIVE
 static char				ethaddr [2 * ETH_ALEN + 1];
 #endif
 
-/* static strings, in iso 8859/1 */
+/* static strings, in UTF-8 */
 static struct usb_string		strings [] = {
 	{ STRING_MANUFACTURER,	manufacturer, },
 	{ STRING_PRODUCT,	product_desc, },
@@ -887,19 +915,21 @@ static struct usb_gadget_strings	stringt
  * complications: class descriptors, and an altsetting.
  */
 static int
-config_buf (enum usb_device_speed speed, u8 *buf, u8 type, unsigned index)
-{
-	int				len;
+config_buf (enum usb_device_speed speed,
+	u8 *buf, u8 type,
+	unsigned index, int is_otg)
+{
+	int					len;
+	const struct usb_config_descriptor	*config;
+	const struct usb_descriptor_header	**function;
 #ifdef CONFIG_USB_GADGET_DUALSPEED
 	int				hs = (speed == USB_SPEED_HIGH);
 
 	if (type == USB_DT_OTHER_SPEED_CONFIG)
 		hs = !hs;
-#define which_config(t)	(hs ? & t ## _config   : & t ## _config)
-#define which_fn(t)	(hs ? & hs_ ## t ## _function : & fs_ ## t ## _function)
+#define which_fn(t)	(hs ? hs_ ## t ## _function : fs_ ## t ## _function)
 #else
-#define	which_config(t)	(& t ## _config)
-#define	which_fn(t)	(& fs_ ## t ## _function)
+#define	which_fn(t)	(fs_ ## t ## _function)
 #endif
 
 	if (index >= device_desc.bNumConfigurations)
@@ -909,15 +939,21 @@ config_buf (enum usb_device_speed speed,
 	/* list the RNDIS config first, to make Microsoft's drivers
 	 * happy. DOCSIS 1.0 needs this too.
 	 */
-	if (device_desc.bNumConfigurations == 2 && index == 0)
-		len = usb_gadget_config_buf (which_config (rndis), buf,
-			USB_BUFSIZ, (const struct usb_descriptor_header **)
-				which_fn (rndis));
-	else
+	if (device_desc.bNumConfigurations == 2 && index == 0) {
+		config = &rndis_config;
+		function = which_fn (rndis);
+	} else
 #endif
-		len = usb_gadget_config_buf (which_config (eth), buf,
-			USB_BUFSIZ, (const struct usb_descriptor_header **)
-				which_fn (eth));
+	{
+		config = &eth_config;
+		function = which_fn (eth);
+	}
+
+	/* for now, don't advertise srp-only devices */
+	if (!is_otg)
+		function++;
+
+	len = usb_gadget_config_buf (config, buf, USB_BUFSIZ, function);
 	if (len < 0)
 		return len;
 	((struct usb_config_descriptor *) buf)->bDescriptorType = type;
@@ -1068,8 +1104,8 @@ set_ether_config (struct eth_dev *dev, i
 		if (dev->status_ep)
 			(void) usb_ep_disable (dev->status_ep);
 #endif
-		dev->status_ep = 0;
-		dev->status = 0;
+		dev->status_ep = NULL;
+		dev->status = NULL;
 #if defined(DEV_CONFIG_SUBSET) || defined(CONFIG_USB_ETH_RNDIS)
 		if (dev->rndis || !dev->cdc) {
 			if (dev->in_ep)
@@ -1078,10 +1114,10 @@ set_ether_config (struct eth_dev *dev, i
 				(void) usb_ep_disable (dev->out_ep);
 		}
 #endif
-		dev->in_ep = 0;
-		dev->in = 0;
-		dev->out_ep = 0;
-		dev->out = 0;
+		dev->in_ep = NULL;
+		dev->in = NULL;
+		dev->out_ep = NULL;
+		dev->out = NULL;
 	} else
 
 	/* activate non-CDC configs right away
@@ -1128,7 +1164,7 @@ static void eth_reset_config (struct eth
 			list_del (&req->list);
 			usb_ep_free_request (dev->in_ep, req);
 		}
-		dev->in_ep = 0;
+		dev->in_ep = NULL;
 	}
 	if (dev->out_ep) {
 		usb_ep_disable (dev->out_ep);
@@ -1138,12 +1174,12 @@ static void eth_reset_config (struct eth
 			list_del (&req->list);
 			usb_ep_free_request (dev->out_ep, req);
 		}
-		dev->out_ep = 0;
+		dev->out_ep = NULL;
 	}
 
 	if (dev->status_ep) {
 		usb_ep_disable (dev->status_ep);
-		dev->status_ep = 0;
+		dev->status_ep = NULL;
 	}
 	dev->config = 0;
 }
@@ -1187,13 +1223,20 @@ eth_set_config (struct eth_dev *dev, uns
 		result = -EINVAL;
 		/* FALL THROUGH */
 	case 0:
-		return result;
+		break;
 	}
 
-	if (result)
-		eth_reset_config (dev);
-	else {
+	if (result) {
+		if (number)
+			eth_reset_config (dev);
+		usb_gadget_vbus_draw(dev->gadget,
+				dev->gadget->is_otg ? 8 : 100);
+	} else {
 		char *speed;
+		unsigned power;
+
+		power = 2 * eth_config.bMaxPower;
+		usb_gadget_vbus_draw(dev->gadget, power);
 
 		switch (gadget->speed) {
 		case USB_SPEED_FULL:	speed = "full"; break;
@@ -1204,8 +1247,8 @@ eth_set_config (struct eth_dev *dev, uns
 		}
 
 		dev->config = number;
-		INFO (dev, "%s speed config #%d: %s, using %s\n",
-				speed, number, driver_desc,
+		INFO (dev, "%s speed config #%d: %d mA, %s, using %s\n",
+				speed, number, power, driver_desc,
 				dev->rndis
 					? "RNDIS"
 					: (dev->cdc
@@ -1364,8 +1407,9 @@ static void eth_setup_complete (struct u
 static void rndis_response_complete (struct usb_ep *ep, struct usb_request *req)
 {
 	if (req->status || req->actual != req->length)
-		DEBUG (dev, "rndis response complete --> %d, %d/%d\n",
-		       req->status, req->actual, req->length);
+		DEBUG ((struct eth_dev *) ep->driver_data,
+			"rndis response complete --> %d, %d/%d\n",
+			req->status, req->actual, req->length);
 
 	/* done sending after CDC_GET_ENCAPSULATED_RESPONSE */
 }
@@ -1404,6 +1448,7 @@ eth_setup (struct usb_gadget *gadget, co
 	/* descriptors just go into the pre-allocated ep0 buffer,
 	 * while config change events may enable network traffic.
 	 */
+	req->complete = eth_setup_complete;
 	switch (ctrl->bRequest) {
 
 	case USB_REQ_GET_DESCRIPTOR:
@@ -1431,7 +1476,8 @@ eth_setup (struct usb_gadget *gadget, co
 		case USB_DT_CONFIG:
 			value = config_buf (gadget->speed, req->buf,
 					ctrl->wValue >> 8,
-					ctrl->wValue & 0xff);
+					ctrl->wValue & 0xff,
+					gadget->is_otg);
 			if (value >= 0)
 				value = min (ctrl->wLength, (u16) value);
 			break;
@@ -1448,6 +1494,10 @@ eth_setup (struct usb_gadget *gadget, co
 	case USB_REQ_SET_CONFIGURATION:
 		if (ctrl->bRequestType != 0)
 			break;
+		if (gadget->a_hnp_support)
+			DEBUG (dev, "HNP available\n");
+		else if (gadget->a_alt_hnp_support)
+			DEBUG (dev, "HNP needs a different root port\n");
 		spin_lock (&dev->lock);
 		value = eth_set_config (dev, ctrl->wValue, GFP_ATOMIC);
 		spin_unlock (&dev->lock);
@@ -1520,7 +1570,7 @@ eth_setup (struct usb_gadget *gadget, co
 		/* FIXME this is wrong, as is the assumption that
 		 * all non-PXA hardware talks real CDC ...
 		 */
-		dev_warn (&gadget->dev, "set_interface ignored!\n");
+		WARN(dev, "set_interface ignored!\n");
 #endif /* DEV_CONFIG_CDC */
 
 done_set_intf:
@@ -1614,6 +1664,8 @@ done_set_intf:
 	/* respond with data transfer before status phase? */
 	if (value >= 0) {
 		req->length = value;
+		req->zero = value < ctrl->wLength
+				&& (value % gadget->ep0->maxpacket) == 0;
 		value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC);
 		if (value < 0) {
 			DEBUG (dev, "ep_queue --> %d\n", value);
@@ -1651,7 +1703,7 @@ eth_disconnect (struct usb_gadget *gadge
 
 static int eth_change_mtu (struct net_device *net, int new_mtu)
 {
-	struct eth_dev	*dev = (struct eth_dev *) net->priv;
+	struct eth_dev	*dev = netdev_priv(net);
 
 	// FIXME if rndis, don't change while link's live
 
@@ -1666,58 +1718,30 @@ static int eth_change_mtu (struct net_de
 
 static struct net_device_stats *eth_get_stats (struct net_device *net)
 {
-	return &((struct eth_dev *) net->priv)->stats;
+	return &((struct eth_dev *)netdev_priv(net))->stats;
 }
 
-static int eth_ethtool_ioctl (struct net_device *net, void __user *useraddr)
+static void eth_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *p)
 {
-	struct eth_dev	*dev = (struct eth_dev *) net->priv;
-	u32		cmd;
-
-	if (get_user (cmd, (u32 __user *)useraddr))
-		return -EFAULT;
-	switch (cmd) {
-
-	case ETHTOOL_GDRVINFO: {	/* get driver info */
-		struct ethtool_drvinfo		info;
-
-		memset (&info, 0, sizeof info);
-		info.cmd = ETHTOOL_GDRVINFO;
-		strncpy (info.driver, shortname, sizeof info.driver);
-		strncpy (info.version, DRIVER_VERSION, sizeof info.version);
-		strncpy (info.fw_version, dev->gadget->name,
-			sizeof info.fw_version);
-		strncpy (info.bus_info, dev->gadget->dev.bus_id,
-			sizeof info.bus_info);
-		if (copy_to_user (useraddr, &info, sizeof (info)))
-			return -EFAULT;
-		return 0;
-		}
-
-	case ETHTOOL_GLINK: {		/* get link status */
-		struct ethtool_value	edata = { ETHTOOL_GLINK };
-
-		edata.data = (dev->gadget->speed != USB_SPEED_UNKNOWN);
-		if (copy_to_user (useraddr, &edata, sizeof (edata)))
-			return -EFAULT;
-		return 0;
-		}
-
-	}
-	/* Note that the ethtool user space code requires EOPNOTSUPP */
-	return -EOPNOTSUPP;
+	struct eth_dev	*dev = netdev_priv(net);
+	memset(p, 0, sizeof *p);
+	strncpy(p->driver, shortname, sizeof p->driver);
+	strncpy(p->version, DRIVER_VERSION, sizeof p->version);
+	strncpy(p->fw_version, dev->gadget->name, sizeof p->fw_version);
+	strncpy (p->bus_info, dev->gadget->dev.bus_id, sizeof p->bus_info);
 }
 
-static int eth_ioctl (struct net_device *net, struct ifreq *rq, int cmd)
+static u32 eth_get_link(struct net_device *net)
 {
-	switch (cmd) {
-	case SIOCETHTOOL:
-		return eth_ethtool_ioctl(net, rq->ifr_data);
-	default:
-		return -EOPNOTSUPP;
-	}
+	struct eth_dev	*dev = netdev_priv(net);
+	return dev->gadget->speed != USB_SPEED_UNKNOWN;
 }
 
+static struct ethtool_ops ops = {
+	.get_drvinfo = eth_get_drvinfo,
+	.get_link = eth_get_link
+};
+
 static void defer_kevent (struct eth_dev *dev, int flag)
 {
 	if (test_and_set_bit (flag, &dev->todo))
@@ -1739,9 +1763,10 @@ rx_submit (struct eth_dev *dev, struct u
 
 	/* Padding up to RX_EXTRA handles minor disagreements with host.
 	 * Normally we use the USB "terminate on short read" convention;
-	 * so allow up to (N*maxpacket)-1, since that memory is normally
-	 * already allocated.  Major loss of synch means -EOVERFLOW; any
-	 * obviously corrupted packets will automatically be discarded. 
+	 * so allow up to (N*maxpacket), since that memory is normally
+	 * already allocated.  Some hardware doesn't deal well with short
+	 * reads (e.g. DMA must be N*maxpacket), so for now don't trim a
+	 * byte off the end (to force hardware errors on overflow).
 	 *
 	 * RNDIS uses internal framing, and explicitly allows senders to
 	 * pad to end-of-packet.  That's potentially nice for speed,
@@ -1754,10 +1779,6 @@ rx_submit (struct eth_dev *dev, struct u
 		size += sizeof (struct rndis_packet_msg_type);
 #endif	
 	size -= size % dev->out_ep->maxpacket;
-#ifdef CONFIG_USB_ETH_RNDIS
-	if (!dev->rndis)
-#endif	
-		size--;
 
 	if ((skb = alloc_skb (size, gfp_flags)) == 0) {
 		DEBUG (dev, "no rx skb\n");
@@ -1815,7 +1836,7 @@ static void rx_complete (struct usb_ep *
 		 * use skb buffers.
 		 */
 		status = netif_rx (skb);
-		skb = 0;
+		skb = NULL;
 		break;
 
 	/* software-driven interface shutdown */
@@ -1849,7 +1870,7 @@ quiesce:
 clean:
 		/* nobody reading rx_reqs, so no dev->lock */
 		list_add (&req->list, &dev->rx_reqs);
-		req = 0;
+		req = NULL;
 	}
 	if (req)
 		rx_submit (dev, req, GFP_ATOMIC);
@@ -1981,10 +2002,10 @@ static void tx_complete (struct usb_ep *
 
 static int eth_start_xmit (struct sk_buff *skb, struct net_device *net)
 {
-	struct eth_dev		*dev = (struct eth_dev *) net->priv;
+	struct eth_dev		*dev = netdev_priv(net);
 	int			length = skb->len;
 	int			retval;
-	struct usb_request	*req = 0;
+	struct usb_request	*req = NULL;
 	unsigned long		flags;
 
 	/* FIXME check dev->cdc_filter to decide whether to send this,
@@ -2082,11 +2103,13 @@ static void rndis_send_media_state (stru
 	}
 }
 
-static void rndis_control_ack_complete (struct usb_ep *ep, struct usb_request *req)
+static void
+rndis_control_ack_complete (struct usb_ep *ep, struct usb_request *req)
 {
 	if (req->status || req->actual != req->length)
-		DEBUG (dev, "rndis control ack complete --> %d, %d/%d\n",
-		       req->status, req->actual, req->length);
+		DEBUG ((struct eth_dev *) ep->driver_data,
+			"rndis control ack complete --> %d, %d/%d\n",
+			req->status, req->actual, req->length);
 
 	usb_ep_free_buffer(ep, req->buf, req->dma, 8);
 	usb_ep_free_request(ep, req);
@@ -2094,7 +2117,7 @@ static void rndis_control_ack_complete (
 
 static int rndis_control_ack (struct net_device *net)
 {
-	struct eth_dev          *dev = (struct eth_dev *) net->priv;
+	struct eth_dev          *dev = netdev_priv(net);
 	u32                     length;
 	struct usb_request      *resp;
 	
@@ -2161,7 +2184,7 @@ static void eth_start (struct eth_dev *d
 
 static int eth_open (struct net_device *net)
 {
-	struct eth_dev		*dev = (struct eth_dev *) net->priv;
+	struct eth_dev		*dev = netdev_priv(net);
 
 	DEBUG (dev, "%s\n", __FUNCTION__);
 	if (netif_carrier_ok (dev->net))
@@ -2171,7 +2194,7 @@ static int eth_open (struct net_device *
 
 static int eth_stop (struct net_device *net)
 {
-	struct eth_dev		*dev = (struct eth_dev *) net->priv;
+	struct eth_dev		*dev = netdev_priv(net);
 
 	VDEBUG (dev, "%s\n", __FUNCTION__);
 	netif_stop_queue (net);
@@ -2182,7 +2205,7 @@ static int eth_stop (struct net_device *
 		);
 
 	/* ensure there are no more active requests */
-	if (dev->gadget->speed != USB_SPEED_UNKNOWN) {
+	if (dev->config) {
 		usb_ep_disable (dev->in_ep);
 		usb_ep_disable (dev->out_ep);
 		if (netif_carrier_ok (dev->net)) {
@@ -2227,7 +2250,7 @@ eth_unbind (struct usb_gadget *gadget)
 				dev->req->buf, dev->req->dma,
 				USB_BUFSIZ);
 		usb_ep_free_request (gadget->ep0, dev->req);
-		dev->req = 0;
+		dev->req = NULL;
 	}
 
 	unregister_netdev (dev->net);
@@ -2235,7 +2258,7 @@ eth_unbind (struct usb_gadget *gadget)
 
 	/* assuming we used keventd, it must quiesce too */
 	flush_scheduled_work ();
-	set_gadget_data (gadget, 0);
+	set_gadget_data (gadget, NULL);
 }
 
 static u8 __init nibble (unsigned char c)
@@ -2316,12 +2339,19 @@ eth_bind (struct usb_gadget *gadget)
 		device_desc.bcdDevice = __constant_cpu_to_le16 (0x0207);
 	} else if (gadget_is_omap (gadget)) {
 		device_desc.bcdDevice = __constant_cpu_to_le16 (0x0208);
+	} else if (gadget_is_lh7a40x(gadget)) {
+		device_desc.bcdDevice = __constant_cpu_to_le16 (0x0209);
+	} else if (gadget_is_n9604(gadget)) {
+		device_desc.bcdDevice = __constant_cpu_to_le16 (0x0210);
+	} else if (gadget_is_pxa27x(gadget)) {
+		device_desc.bcdDevice = __constant_cpu_to_le16 (0x0211);
 	} else {
 		/* can't assume CDC works.  don't want to default to
 		 * anything less functional on CDC-capable hardware,
 		 * so we fail in this case.
 		 */
-		printk (KERN_ERR "%s: controller '%s' not recognized\n",
+		printk (KERN_ERR "%s: "
+			"controller '%s' not recognized\n",
 			shortname, gadget->name);
 		return -ENODEV;
 	}
@@ -2400,7 +2430,8 @@ autoconf_fail:
 			EP_STATUS_NAME = ep->name;
 			ep->driver_data = ep;	/* claim */
 		} else if (rndis) {
-			printk (KERN_ERR "%s: can't run RNDIS on %s\n",
+			printk (KERN_ERR "%s: "
+				"can't run RNDIS on %s\n",
 				shortname, gadget->name);
 			return -ENODEV;
 		} else if (cdc) {
@@ -2444,10 +2475,20 @@ autoconf_fail:
 	device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket;
 	usb_gadget_set_selfpowered (gadget);
 
+	if (gadget->is_otg) {
+		otg_descriptor.bmAttributes |= USB_OTG_HNP,
+		eth_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+		eth_config.bMaxPower = 4;
+#ifdef	CONFIG_USB_ETH_RNDIS
+		rndis_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+		rndis_config.bMaxPower = 4;
+#endif
+	}
+
  	net = alloc_etherdev (sizeof *dev);
  	if (!net)
 		return status;
-	dev = net->priv;
+	dev = netdev_priv(net);
 	spin_lock_init (&dev->lock);
 	INIT_WORK (&dev->work, eth_work, dev);
 	INIT_LIST_HEAD (&dev->tx_reqs);
@@ -2491,7 +2532,7 @@ autoconf_fail:
 	net->stop = eth_stop;
 	// watchdog_timeo, tx_timeout ...
 	// set_multicast_list
-	net->do_ioctl = eth_ioctl;
+	SET_ETHTOOL_OPS(net, &ops);
 
 	/* preallocate control response and buffer */
 	dev->req = usb_ep_alloc_request (gadget->ep0, GFP_KERNEL);
@@ -2572,7 +2613,7 @@ fail0:
 	return status;
 
 fail1:
-	pr_debug ("%s: register_netdev failed, %d\n", shortname, status);
+	DEBUG (dev, "register_netdev failed, %d\n", status);
 fail:
 	eth_unbind (gadget);
 	return status;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/usb/gadget/gadget_chips.h linux-2.4.29-pre3/drivers/usb/gadget/gadget_chips.h
--- linux-2.4.28/drivers/usb/gadget/gadget_chips.h	2004-08-07 23:26:05.000000000 +0000
+++ linux-2.4.29-pre3/drivers/usb/gadget/gadget_chips.h	2004-12-22 16:05:53.556277536 +0000
@@ -44,6 +44,12 @@
 #define	gadget_is_sa1100(g)	0
 #endif
 
+#ifdef CONFIG_USB_GADGET_LH7A40X
+#define	gadget_is_lh7a40x(g)	!strcmp("lh7a40x_udc", (g)->name)
+#else
+#define	gadget_is_lh7a40x(g)	0
+#endif
+
 #ifdef CONFIG_USB_GADGET_MQ11XX
 #define	gadget_is_mq11xx(g)	!strcmp("mq11xx_udc", (g)->name)
 #else
@@ -56,6 +62,18 @@
 #define	gadget_is_omap(g)	0
 #endif
 
+#ifdef CONFIG_USB_GADGET_N9604
+#define	gadget_is_n9604(g)	!strcmp("n9604_udc", (g)->name)
+#else
+#define	gadget_is_n9604(g)	0
+#endif
+
+#ifdef CONFIG_USB_GADGET_PXA27X
+#define	gadget_is_pxa27x(g)	!strcmp("pxa27x_udc", (g)->name)
+#else
+#define	gadget_is_pxa27x(g)	0
+#endif
+
 // CONFIG_USB_GADGET_AT91RM9200
 // CONFIG_USB_GADGET_SX2
 // CONFIG_USB_GADGET_AU1X00
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/usb/gadget/rndis.c linux-2.4.29-pre3/drivers/usb/gadget/rndis.c
--- linux-2.4.28/drivers/usb/gadget/rndis.c	2004-08-07 23:26:05.000000000 +0000
+++ linux-2.4.29-pre3/drivers/usb/gadget/rndis.c	2004-12-22 16:07:54.992816376 +0000
@@ -70,8 +70,6 @@ MODULE_PARM_DESC (rndis_debug, "enable d
 
 #define RNDIS_MAX_CONFIGS	1
 
-static struct proc_dir_entry *rndis_connect_dir;
-static struct proc_dir_entry *rndis_connect_state [RNDIS_MAX_CONFIGS];
 
 static rndis_params rndis_per_dev_params [RNDIS_MAX_CONFIGS];
 
@@ -1275,7 +1273,12 @@ int rndis_rm_hdr (u8 *buf, u32 *length)
 	return 0;
 }
 
-int rndis_proc_read (char *page, char **start, off_t off, int count, int *eof, 
+
+#ifdef	CONFIG_USB_GADGET_DEBUG_FILES
+
+#include <asm/uaccess.h>
+
+static int rndis_proc_read (char *page, char **start, off_t off, int count, int *eof, 
 		     void *data)
 {
 	char *out = page;
@@ -1320,14 +1323,18 @@ int rndis_proc_read (char *page, char **
 	return len;
 }
 
-int rndis_proc_write (struct file *file, const char *buffer, 
+static int rndis_proc_write (struct file *file, const char __user *buffer, 
 		      unsigned long count, void *data)
 {
+	rndis_params *p = data;
 	u32 speed = 0;
 	int i, fl_speed = 0;
 	
 	for (i = 0; i < count; i++) {
-		switch (*buffer) {
+		char c;
+		if (get_user(c, buffer))
+			return -EFAULT;
+		switch (c) {
 		case '0':
 		case '1':
 		case '2':
@@ -1339,21 +1346,19 @@ int rndis_proc_write (struct file *file,
 		case '8':
 		case '9':
 			fl_speed = 1;
-			speed = speed*10 + *buffer - '0';
+			speed = speed*10 + c - '0';
 			break;
 		case 'C':
 		case 'c':
-			rndis_signal_connect (((rndis_params *) data)
-				->confignr);
+			rndis_signal_connect (p->confignr);
 			break;
 		case 'D':
 		case 'd':
-			rndis_signal_disconnect (((rndis_params *) data)
-				->confignr);
+			rndis_signal_disconnect(p->confignr);
 			break;
 		default: 
-			if (fl_speed) ((rndis_params *) data)->speed = speed;
-			else DEBUG ("%c is not valid\n", *buffer);
+			if (fl_speed) p->speed = speed;
+			else DEBUG ("%c is not valid\n", c);
 			break;
 		}
 		
@@ -1363,43 +1368,40 @@ int rndis_proc_write (struct file *file,
 	return count;
 }
 
+#define	NAME_TEMPLATE	"driver/rndis-%03d"
+
+static struct proc_dir_entry *rndis_connect_state [RNDIS_MAX_CONFIGS];
+
+#endif	/* CONFIG_USB_GADGET_DEBUG_FILES */
+
+
 int __init rndis_init (void)
 {
 	u8 i;
-	char name [4];
 
-	/* FIXME this should probably be /proc/driver/rndis,
-	 * and only if debugging is enabled
-	 */
-	
-	if (!(rndis_connect_dir =  proc_mkdir ("rndis", NULL))) {
-		printk (KERN_ERR "%s: couldn't create /proc/rndis entry", 
-			__FUNCTION__);
-		return -EIO;
-	}
-	
 	for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {
-		sprintf (name, "%03d", i);
+#ifdef	CONFIG_USB_GADGET_DEBUG_FILES
+		char name [20];
+
+		sprintf (name, NAME_TEMPLATE, i);
 		if (!(rndis_connect_state [i]
-				= create_proc_entry (name, 0660,
-						rndis_connect_dir))) 
+				= create_proc_entry (name, 0660, NULL))) 
 		{
 			DEBUG ("%s :remove entries", __FUNCTION__);
-			for (i--; i > 0; i--) {
-				sprintf (name, "%03d", i);
-				remove_proc_entry (name, rndis_connect_dir);
+			while (i) {
+				sprintf (name, NAME_TEMPLATE, --i);
+				remove_proc_entry (name, NULL);
 			}
 			DEBUG ("\n");
-			
-			remove_proc_entry ("000", rndis_connect_dir);
-			remove_proc_entry ("rndis", NULL);
 			return -EIO;
 		}
+
 		rndis_connect_state [i]->nlink = 1;
 		rndis_connect_state [i]->write_proc = rndis_proc_write;
 		rndis_connect_state [i]->read_proc = rndis_proc_read;
 		rndis_connect_state [i]->data = (void *)
 				(rndis_per_dev_params + i);
+#endif
 		rndis_per_dev_params [i].confignr = i;
 		rndis_per_dev_params [i].used = 0;
 		rndis_per_dev_params [i].state = RNDIS_UNINITIALIZED;
@@ -1413,14 +1415,14 @@ int __init rndis_init (void)
 
 void rndis_exit (void)
 {
+#ifdef	CONFIG_USB_GADGET_DEBUG_FILES
 	u8 i;
-	char name [4];
+	char name [20];
 	
 	for (i = 0; i < RNDIS_MAX_CONFIGS; i++) {
-		sprintf (name, "%03d", i);
-		remove_proc_entry (name, rndis_connect_dir);
+		sprintf (name, NAME_TEMPLATE, i);
+		remove_proc_entry (name, NULL);
 	}
-	remove_proc_entry ("rndis", NULL);
-	return;
+#endif
 }
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/usb/gadget/zero.c linux-2.4.29-pre3/drivers/usb/gadget/zero.c
--- linux-2.4.28/drivers/usb/gadget/zero.c	2004-08-07 23:26:05.000000000 +0000
+++ linux-2.4.29-pre3/drivers/usb/gadget/zero.c	2004-12-22 16:05:45.733466784 +0000
@@ -200,8 +200,13 @@ MODULE_PARM (autoresume, "i");
  * DO NOT REUSE THESE IDs with a protocol-incompatible driver!!  Ever!!
  * Instead:  allocate your own, using normal USB-IF procedures.
  */
+#ifndef	CONFIG_USB_ZERO_HNPTEST
 #define DRIVER_VENDOR_NUM	0x0525		/* NetChip */
 #define DRIVER_PRODUCT_NUM	0xa4a0		/* Linux-USB "Gadget Zero" */
+#else
+#define DRIVER_VENDOR_NUM	0x1a0a		/* OTG test device IDs */
+#define DRIVER_PRODUCT_NUM	0xbadd
+#endif
 
 /*-------------------------------------------------------------------------*/
 
@@ -265,6 +270,14 @@ loopback_config = {
 	.bMaxPower =		1,	/* self-powered */
 };
 
+static struct usb_otg_descriptor
+otg_descriptor = {
+	.bLength =		sizeof otg_descriptor,
+	.bDescriptorType =	USB_DT_OTG,
+
+	.bmAttributes =		USB_OTG_SRP,
+};
+
 /* one interface in each configuration */
 
 static const struct usb_interface_descriptor
@@ -308,17 +321,19 @@ fs_sink_desc = {
 };
 
 static const struct usb_descriptor_header *fs_source_sink_function [] = {
+	(struct usb_descriptor_header *) &otg_descriptor,
 	(struct usb_descriptor_header *) &source_sink_intf,
 	(struct usb_descriptor_header *) &fs_sink_desc,
 	(struct usb_descriptor_header *) &fs_source_desc,
-	0,
+	NULL,
 };
 
 static const struct usb_descriptor_header *fs_loopback_function [] = {
+	(struct usb_descriptor_header *) &otg_descriptor,
 	(struct usb_descriptor_header *) &loopback_intf,
 	(struct usb_descriptor_header *) &fs_sink_desc,
 	(struct usb_descriptor_header *) &fs_source_desc,
-	0,
+	NULL,
 };
 
 #ifdef	CONFIG_USB_GADGET_DUALSPEED
@@ -362,17 +377,19 @@ dev_qualifier = {
 };
 
 static const struct usb_descriptor_header *hs_source_sink_function [] = {
+	(struct usb_descriptor_header *) &otg_descriptor,
 	(struct usb_descriptor_header *) &source_sink_intf,
 	(struct usb_descriptor_header *) &hs_source_desc,
 	(struct usb_descriptor_header *) &hs_sink_desc,
-	0,
+	NULL,
 };
 
 static const struct usb_descriptor_header *hs_loopback_function [] = {
+	(struct usb_descriptor_header *) &otg_descriptor,
 	(struct usb_descriptor_header *) &loopback_intf,
 	(struct usb_descriptor_header *) &hs_source_desc,
 	(struct usb_descriptor_header *) &hs_sink_desc,
-	0,
+	NULL,
 };
 
 /* maxpacket and other transfer characteristics vary by speed. */
@@ -385,10 +402,10 @@ static const struct usb_descriptor_heade
 
 #endif	/* !CONFIG_USB_GADGET_DUALSPEED */
 
-static char				manufacturer [40];
+static char				manufacturer [50];
 static char				serial [40];
 
-/* static strings, in iso 8859/1 */
+/* static strings, in UTF-8 */
 static struct usb_string		strings [] = {
 	{ STRING_MANUFACTURER, manufacturer, },
 	{ STRING_PRODUCT, longname, },
@@ -450,6 +467,10 @@ config_buf (struct usb_gadget *gadget,
 			? fs_source_sink_function
 			: fs_loopback_function;
 
+	/* for now, don't advertise srp-only devices */
+	if (!gadget->is_otg)
+		function++;
+
 	len = usb_gadget_config_buf (is_source_sink
 					? &source_sink_config
 					: &loopback_config,
@@ -474,7 +495,7 @@ alloc_ep_req (struct usb_ep *ep, unsigne
 				&req->dma, GFP_ATOMIC);
 		if (!req->buf) {
 			usb_ep_free_request (ep, req);
-			req = 0;
+			req = NULL;
 		}
 	}
 	return req;
@@ -491,7 +512,7 @@ static void free_ep_req (struct usb_ep *
 
 /* optionally require specific source/sink data patterns  */
 
-static inline int
+static int
 check_read_data (
 	struct zero_dev		*dev,
 	struct usb_ep		*ep,
@@ -525,7 +546,7 @@ check_read_data (
 	return 0;
 }
 
-static inline void
+static void
 reinit_write_data (
 	struct zero_dev		*dev,
 	struct usb_ep		*ep,
@@ -605,7 +626,7 @@ source_sink_start_ep (struct usb_ep *ep,
 
 	req = alloc_ep_req (ep, buflen);
 	if (!req)
-		return 0;
+		return NULL;
 
 	memset (req->buf, 0, req->length);
 	req->complete = source_sink_complete;
@@ -619,7 +640,7 @@ source_sink_start_ep (struct usb_ep *ep,
 
 		ERROR (dev, "start %s --> %d\n", ep->name, status);
 		free_ep_req (ep, req);
-		req = 0;
+		req = NULL;
 	}
 
 	return req;
@@ -810,13 +831,14 @@ static void zero_reset_config (struct ze
 	 */
 	if (dev->in_ep) {
 		usb_ep_disable (dev->in_ep);
-		dev->in_ep = 0;
+		dev->in_ep = NULL;
 	}
 	if (dev->out_ep) {
 		usb_ep_disable (dev->out_ep);
-		dev->out_ep = 0;
+		dev->out_ep = NULL;
 	}
 	dev->config = 0;
+	del_timer (&dev->resume);
 }
 
 /* change our operational config.  this code must agree with the code
@@ -908,6 +930,7 @@ zero_setup (struct usb_gadget *gadget, c
 	/* usually this stores reply data in the pre-allocated ep0 buffer,
 	 * but config change events will reconfigure hardware.
 	 */
+	req->zero = 0;
 	switch (ctrl->bRequest) {
 
 	case USB_REQ_GET_DESCRIPTOR:
@@ -943,7 +966,8 @@ zero_setup (struct usb_gadget *gadget, c
 		case USB_DT_STRING:
 			/* wIndex == language code.
 			 * this driver only handles one language, you can
-			 * add others even if they don't use iso8859/1
+			 * add string tables for other languages, using
+			 * any UTF-8 characters
 			 */
 			value = usb_gadget_get_string (&stringtab,
 					ctrl->wValue & 0xff, req->buf);
@@ -957,6 +981,12 @@ zero_setup (struct usb_gadget *gadget, c
 	case USB_REQ_SET_CONFIGURATION:
 		if (ctrl->bRequestType != 0)
 			goto unknown;
+		if (gadget->a_hnp_support)
+			DBG (dev, "HNP available\n");
+		else if (gadget->a_alt_hnp_support)
+			DBG (dev, "HNP needs a different root port\n");
+		else
+			VDBG (dev, "HNP inactive\n");
 		spin_lock (&dev->lock);
 		value = zero_set_config (dev, ctrl->wValue, GFP_ATOMIC);
 		spin_unlock (&dev->lock);
@@ -1043,6 +1073,8 @@ unknown:
 	/* respond with data transfer before status phase? */
 	if (value >= 0) {
 		req->length = value;
+		req->zero = value < ctrl->wLength
+				&& (value % gadget->ep0->maxpacket) == 0;
 		value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC);
 		if (value < 0) {
 			DBG (dev, "ep_queue --> %d\n", value);
@@ -1084,8 +1116,10 @@ zero_autoresume (unsigned long _dev)
 	/* normally the host would be woken up for something
 	 * more significant than just a timer firing...
 	 */
-	status = usb_gadget_wakeup (dev->gadget);
-	DBG (dev, "wakeup --> %d\n", status);
+	if (dev->gadget->speed != USB_SPEED_UNKNOWN) {
+		status = usb_gadget_wakeup (dev->gadget);
+		DBG (dev, "wakeup --> %d\n", status);
+	}
 }
 
 /*-------------------------------------------------------------------------*/
@@ -1102,7 +1136,7 @@ zero_unbind (struct usb_gadget *gadget)
 		free_ep_req (gadget->ep0, dev->req);
 	del_timer_sync (&dev->resume);
 	kfree (dev);
-	set_gadget_data (gadget, 0);
+	set_gadget_data (gadget, NULL);
 }
 
 static int
@@ -1158,6 +1192,12 @@ autoconf_fail:
 		device_desc.bcdDevice = __constant_cpu_to_le16 (0x0207);
 	} else if (gadget_is_omap (gadget)) {
 		device_desc.bcdDevice = __constant_cpu_to_le16 (0x0208);
+	} else if (gadget_is_lh7a40x(gadget)) {
+		device_desc.bcdDevice = __constant_cpu_to_le16 (0x0209);
+	} else if (gadget_is_n9604(gadget)) {
+		device_desc.bcdDevice = __constant_cpu_to_le16 (0x0210);
+	} else if (gadget_is_pxa27x(gadget)) {
+		device_desc.bcdDevice = __constant_cpu_to_le16 (0x0211);
 	} else {
 		/* gadget zero is so simple (for now, no altsettings) that
 		 * it SHOULD NOT have problems with bulk-capable hardware.
@@ -1203,6 +1243,18 @@ autoconf_fail:
 	hs_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress;
 #endif
 
+	if (gadget->is_otg) {
+		otg_descriptor.bmAttributes |= USB_OTG_HNP,
+		source_sink_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+		loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+	}
+
+	if (gadget->is_otg) {
+		otg_descriptor.bmAttributes |= USB_OTG_HNP,
+		source_sink_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+		loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+	}
+
 	usb_gadget_set_selfpowered (gadget);
 
 	init_timer (&dev->resume);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/usb/host/usb-ohci.c linux-2.4.29-pre3/drivers/usb/host/usb-ohci.c
--- linux-2.4.28/drivers/usb/host/usb-ohci.c	2004-04-14 13:05:33.000000000 +0000
+++ linux-2.4.29-pre3/drivers/usb/host/usb-ohci.c	2004-12-22 16:05:59.679346688 +0000
@@ -143,7 +143,7 @@ static void ohci_complete_add(struct ohc
 		ohci->complete_head = urb;
 		ohci->complete_tail = urb;
 	} else {
-		ohci->complete_head->hcpriv = urb;
+		ohci->complete_tail->hcpriv = urb;
 		ohci->complete_tail = urb;
 	}
 }
@@ -677,7 +677,8 @@ static int sohci_submit_urb (struct urb 
 		return -ENOMEM;
 	}
 	memset (urb_priv, 0, sizeof (urb_priv_t) + size * sizeof (td_t *));
-	
+	init_waitqueue_head (&urb_priv->wait);
+
 	/* fill the private part of the URB */
 	urb_priv->length = size;
 	urb_priv->ed = ed;	
@@ -823,12 +824,10 @@ static int sohci_unlink_urb (struct urb 
 			urb_priv->ed->state |= ED_URB_DEL;
 
 			if (!(urb->transfer_flags & USB_ASYNC_UNLINK)) {
-				DECLARE_WAIT_QUEUE_HEAD (unlink_wakeup); 
 				DECLARE_WAITQUEUE (wait, current);
 				int timeout = OHCI_UNLINK_TIMEOUT;
 
-				add_wait_queue (&unlink_wakeup, &wait);
-				urb_priv->wait = &unlink_wakeup;
+				add_wait_queue(&urb_priv->wait, &wait);
 				spin_unlock_irqrestore(&ohci->ohci_lock, flags);
 
 				/* wait until all TDs are deleted */
@@ -838,7 +837,16 @@ static int sohci_unlink_urb (struct urb 
 					set_current_state(TASK_UNINTERRUPTIBLE);
 				}
 				set_current_state(TASK_RUNNING);
-				remove_wait_queue (&unlink_wakeup, &wait); 
+
+				/*
+				 * A waitqueue head is self-locked, but we try
+				 * to interlock with the dl_del_urb() which may
+				 * be doing wake_up() right now, least
+				 * urb->complete poisons over the urb->wait.
+				 */
+				spin_lock_irqsave(&ohci->ohci_lock, flags);
+				remove_wait_queue(&urb_priv->wait, &wait); 
+				spin_unlock_irqrestore(&ohci->ohci_lock, flags);
 				if (urb->status == USB_ST_URB_PENDING) {
 					err ("unlink URB timeout");
 					return -ETIMEDOUT;
@@ -943,18 +951,16 @@ static int sohci_free_dev (struct usb_de
 				warn ("TD leak, %d", cnt);
 
 			} else if (!in_interrupt ()) {
-				DECLARE_WAIT_QUEUE_HEAD (freedev_wakeup); 
 				DECLARE_WAITQUEUE (wait, current);
 				int timeout = OHCI_UNLINK_TIMEOUT;
 
 				/* SF interrupt handler calls dl_del_list */
-				add_wait_queue (&freedev_wakeup, &wait);
-				dev->wait = &freedev_wakeup;
+				add_wait_queue (&dev->wait, &wait);
 				set_current_state(TASK_UNINTERRUPTIBLE);
 				while (timeout && dev->ed_cnt)
 					timeout = schedule_timeout (timeout);
 				set_current_state(TASK_RUNNING);
-				remove_wait_queue (&freedev_wakeup, &wait);
+				remove_wait_queue (&dev->wait, &wait);
 				if (dev->ed_cnt) {
 					err ("free device %d timeout", usb_dev->devnum);
 					return -ETIMEDOUT;
@@ -1560,7 +1566,7 @@ static void dl_transfer_length(td_t * td
 
 static void dl_del_urb (ohci_t *ohci, struct urb * urb)
 {
-	wait_queue_head_t * wait_head = ((urb_priv_t *)(urb->hcpriv))->wait;
+ 	urb_priv_t * urb_priv = urb->hcpriv;
 
 	urb_rm_priv_locked (urb);
 
@@ -1571,8 +1577,7 @@ static void dl_del_urb (ohci_t *ohci, st
 		urb->status = -ENOENT;
 
 		/* unblock sohci_unlink_urb */
-		if (wait_head)
-			wake_up (wait_head);
+		wake_up(&urb_priv->wait);
 	}
 }
 
@@ -1664,13 +1669,8 @@ static void dl_del_list (ohci_t  * ohci,
 			ed->state = ED_NEW;
 			hash_free_ed(ohci, ed);
    	 		/* if all eds are removed wake up sohci_free_dev */
-   	 		if (!--dev->ed_cnt) {
-				wait_queue_head_t *wait_head = dev->wait;
-
-				dev->wait = 0;
-				if (wait_head)
-					wake_up (wait_head);
-			}
+   	 		if (!--dev->ed_cnt)
+				wake_up(&dev->wait);
    	 	} else {
    	 		ed->state &= ~ED_URB_DEL;
 			tdHeadP = dma_to_td (ohci, le32_to_cpup (&ed->hwHeadP) & 0xfffffff0);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/usb/host/usb-ohci.h linux-2.4.29-pre3/drivers/usb/host/usb-ohci.h
--- linux-2.4.28/drivers/usb/host/usb-ohci.h	2004-04-14 13:05:33.000000000 +0000
+++ linux-2.4.29-pre3/drivers/usb/host/usb-ohci.h	2004-12-22 16:05:55.324008800 +0000
@@ -336,7 +336,7 @@ typedef struct 
 	__u16 length;	// number of tds associated with this request
 	__u16 td_cnt;	// number of tds already serviced
 	int   state;
-	wait_queue_head_t * wait;
+	wait_queue_head_t wait;
 	td_t * td[0];	// list pointer to all corresponding TDs associated with this request
 
 } urb_priv_t;
@@ -417,7 +417,7 @@ struct ohci_device {
 	ed_t 	ed[NUM_EDS];
 	dma_addr_t dma;
 	int ed_cnt;
-	wait_queue_head_t * wait;
+	wait_queue_head_t wait;
 };
 
 // #define ohci_to_usb(ohci)	((ohci)->usb)
@@ -626,6 +626,7 @@ dev_alloc (struct ohci *hc, int mem_flag
 	dev = pci_pool_alloc (hc->dev_cache, mem_flags, &dma);
 	if (dev) {
 		memset (dev, 0, sizeof (*dev));
+		init_waitqueue_head (&dev->wait);
 		dev->dma = dma;
 		offset = ((char *)&dev->ed) - ((char *)dev);
 		for (i = 0; i < NUM_EDS; i++, offset += sizeof dev->ed [0])
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/usb/serial/digi_acceleport.c linux-2.4.29-pre3/drivers/usb/serial/digi_acceleport.c
--- linux-2.4.28/drivers/usb/serial/digi_acceleport.c	2002-11-28 23:53:14.000000000 +0000
+++ linux-2.4.29-pre3/drivers/usb/serial/digi_acceleport.c	2004-12-22 16:06:39.364313656 +0000
@@ -614,14 +614,7 @@ static void digi_wakeup_write( struct us
 	wake_up_interruptible( &port->write_wait );
 
 	/* wake up line discipline */
-	if( (tty->flags & (1 << TTY_DO_WRITE_WAKEUP))
-	&& tty->ldisc.write_wakeup )
-		(tty->ldisc.write_wakeup)(tty);
-
-	/* wake up other tty processes */
-	wake_up_interruptible( &tty->write_wait );
-	/* For 2.2.16 backport -- wake_up_interruptible( &tty->poll_wait ); */
-
+	tty_wakeup(tty);
 }
 
 
@@ -1557,8 +1550,7 @@ dbg( "digi_close: TOP: port=%d, open_cou
 	/* flush driver and line discipline buffers */
 	if( tty->driver.flush_buffer )
 		tty->driver.flush_buffer( tty );
-	if( tty->ldisc.flush_buffer )
-		tty->ldisc.flush_buffer( tty );
+	tty_ldisc_flush(tty);
 
 	if (port->serial->dev) {
 		/* wait for transmit idle */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/usb/serial/io_edgeport.c linux-2.4.29-pre3/drivers/usb/serial/io_edgeport.c
--- linux-2.4.28/drivers/usb/serial/io_edgeport.c	2004-08-07 23:26:05.000000000 +0000
+++ linux-2.4.29-pre3/drivers/usb/serial/io_edgeport.c	2004-12-22 16:05:33.111385632 +0000
@@ -902,12 +902,7 @@ static void edge_bulk_out_data_callback 
 
 	if (tty && edge_port->open) {
 		/* let the tty driver wakeup if it has a special write_wakeup function */
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) {
-			(tty->ldisc.write_wakeup)(tty);
-		}
-
-		/* tell the tty driver that something has changed */
-		wake_up_interruptible(&tty->write_wait);
+		tty_wakeup(tty);
 	}
 
 	// Release the Write URB
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/usb/serial/io_ti.c linux-2.4.29-pre3/drivers/usb/serial/io_ti.c
--- linux-2.4.28/drivers/usb/serial/io_ti.c	2003-11-28 18:26:20.000000000 +0000
+++ linux-2.4.29-pre3/drivers/usb/serial/io_ti.c	2004-12-22 16:07:44.594397176 +0000
@@ -1800,12 +1800,7 @@ static void edge_bulk_out_callback (stru
 	tty = port->tty;
 	if (tty) {
 		/* let the tty driver wakeup if it has a special write_wakeup function */
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) {
-			(tty->ldisc.write_wakeup)(tty);
-		}
-
-		/* tell the tty driver that something has changed */
-		wake_up_interruptible(&tty->write_wait);
+		tty_wakeup(tty);
 	}
 }
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/usb/serial/keyspan_pda.c linux-2.4.29-pre3/drivers/usb/serial/keyspan_pda.c
--- linux-2.4.28/drivers/usb/serial/keyspan_pda.c	2003-11-28 18:26:20.000000000 +0000
+++ linux-2.4.29-pre3/drivers/usb/serial/keyspan_pda.c	2004-12-22 16:07:07.671010384 +0000
@@ -183,13 +183,7 @@ static void keyspan_pda_wakeup_write( st
 	wake_up_interruptible( &port->write_wait );
 
 	/* wake up line discipline */
-	if( (tty->flags & (1 << TTY_DO_WRITE_WAKEUP))
-	&& tty->ldisc.write_wakeup )
-		(tty->ldisc.write_wakeup)(tty);
-
-	/* wake up other tty processes */
-	wake_up_interruptible( &tty->write_wait );
-	/* For 2.2.16 backport -- wake_up_interruptible( &tty->poll_wait ); */
+	tty_wakeup(tty);
 }
 
 static void keyspan_pda_request_unthrottle( struct usb_serial *serial )
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/usb/serial/mct_u232.c linux-2.4.29-pre3/drivers/usb/serial/mct_u232.c
--- linux-2.4.28/drivers/usb/serial/mct_u232.c	2004-08-07 23:26:05.000000000 +0000
+++ linux-2.4.29-pre3/drivers/usb/serial/mct_u232.c	2004-12-22 16:07:09.851678872 +0000
@@ -569,11 +569,7 @@ static void mct_u232_write_bulk_callback
 
 	if (write_blocking) {
 		wake_up_interruptible(&port->write_wait);
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup)(tty);
-		wake_up_interruptible(&tty->write_wait);
-		
+		tty_wakeup(tty);
 	} else {
 		/* from generic_write_bulk_callback */
 		queue_task(&port->tqueue, &tq_immediate);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/usb/serial/usbserial.c linux-2.4.29-pre3/drivers/usb/serial/usbserial.c
--- linux-2.4.28/drivers/usb/serial/usbserial.c	2004-12-22 16:17:18.760110720 +0000
+++ linux-2.4.29-pre3/drivers/usb/serial/usbserial.c	2004-12-22 16:06:30.227702632 +0000
@@ -1326,6 +1326,7 @@ static void port_softint(void *private)
 	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
 	struct tty_struct *tty;
 	unsigned long flags;
+	struct tty_ldisc *ld;
 
 	dbg("%s - port %d", __FUNCTION__, port->number);
 	
@@ -1341,9 +1342,15 @@ static void port_softint(void *private)
 	if (!tty)
 		return;
 
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) {
-		dbg("%s - write wakeup call.", __FUNCTION__);
-		(tty->ldisc.write_wakeup)(tty);
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP))) {
+		ld = tty_ldisc_ref(tty);
+		if(ld) {
+			if(ld->write_wakeup) {
+				ld->write_wakeup(tty);
+				dbg("%s - write wakeup call.", __FUNCTION__);
+			}
+			tty_ldisc_deref(ld);
+		}
 	}
 
 	wake_up_interruptible(&tty->write_wait);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/video/fbmem.c linux-2.4.29-pre3/drivers/video/fbmem.c
--- linux-2.4.28/drivers/video/fbmem.c	2004-08-07 23:26:05.000000000 +0000
+++ linux-2.4.29-pre3/drivers/video/fbmem.c	2004-12-22 16:05:30.697752560 +0000
@@ -410,6 +410,7 @@ fb_read(struct file *file, char *buf, si
 	struct fb_info *info = registered_fb[fbidx];
 	struct fb_ops *fb = info->fbops;
 	struct fb_fix_screeninfo fix;
+	unsigned int size;
 
 	if (! fb || ! info->disp)
 		return -ENODEV;
@@ -418,10 +419,12 @@ fb_read(struct file *file, char *buf, si
 		return -EINVAL;
 
 	fb->fb_get_fix(&fix,PROC_CONSOLE(info), info);
-	if (p >= fix.smem_len)
+	size = info->mapped_vram ? info->mapped_vram : fix.smem_len;
+	
+	if (p >= size)
 	    return 0;
-	if (count > fix.smem_len - p)
-		count = fix.smem_len - p;
+	if (count > size - p)
+		count = size - p;
 	if (count) {
 	    char *base_addr;
 
@@ -444,6 +447,7 @@ fb_write(struct file *file, const char *
 	struct fb_ops *fb = info->fbops;
 	struct fb_fix_screeninfo fix;
 	int err;
+	unsigned int size;
 
 	if (! fb || ! info->disp)
 		return -ENODEV;
@@ -452,11 +456,13 @@ fb_write(struct file *file, const char *
 		return -EINVAL;
 
 	fb->fb_get_fix(&fix, PROC_CONSOLE(info), info);
-	if (p > fix.smem_len)
+	size = info->mapped_vram ? info->mapped_vram : fix.smem_len;
+	
+	if (p > size)
 	    return -ENOSPC;
 	err = 0;
-	if (count > fix.smem_len - p) {
-	    count = fix.smem_len - p;
+	if (count > size - p) {
+	    count = size - p;
 	    err = -ENOSPC;
 	}
 	if (count) {
@@ -619,7 +625,10 @@ fb_mmap(struct file *file, struct vm_are
 
 	/* frame buffer memory */
 	start = fix.smem_start;
-	len = PAGE_ALIGN((start & ~PAGE_MASK)+fix.smem_len);
+	if (info->mapped_vram)
+		len = PAGE_ALIGN((start & ~PAGE_MASK) + info->mapped_vram);
+	else
+		len = PAGE_ALIGN((start & ~PAGE_MASK) + fix.smem_len);
 	if (off >= len) {
 		/* memory mapped io */
 		off -= len;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/drivers/video/radeonfb.c linux-2.4.29-pre3/drivers/video/radeonfb.c
--- linux-2.4.28/drivers/video/radeonfb.c	2004-12-22 16:17:18.862095216 +0000
+++ linux-2.4.29-pre3/drivers/video/radeonfb.c	2004-12-22 16:07:43.596548872 +0000
@@ -176,7 +176,8 @@
 #define RTRACE		if(0) printk
 #endif
 
-
+#define MAX_MAPPED_VRAM (2048*2048*4)
+#define MIN_MAPPED_VRAM (1024*768*1)
 
 enum radeon_chips {
 	RADEON_QD,
@@ -218,6 +219,7 @@ enum radeon_chips {
 	RADEON_NH,
 	RADEON_NI,
 	RADEON_AP,
+	RADEON_AQ,
 	RADEON_AR,
 };
 
@@ -279,6 +281,7 @@ static struct radeon_chip_info {
 	{ "9800 NH", RADEON_R350 },
 	{ "9800 NI", RADEON_R350 },
 	{ "9600 AP", RADEON_RV350 },
+	{ "9600 AQ", RADEON_RV350 },
 	{ "9600 AR", RADEON_RV350 },
 };
 
@@ -334,6 +337,7 @@ static struct pci_device_id radeonfb_pci
 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Yd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_Yd},
 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_AD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_AD},
 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_AP, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_AP},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_AQ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_AQ},
 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_AR, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_AR},
 	{ 0, }
 };
@@ -499,7 +503,7 @@ struct radeonfb_info {
 
 	short chipset;
 	unsigned char arch;
-	int video_ram;
+	unsigned int video_ram;
 	u8 rev;
 	int pitch, bpp, depth;
 	int xres, yres, pixclock;
@@ -1626,6 +1630,7 @@ static int radeonfb_pci_register (struct
 				  const struct pci_device_id *ent)
 {
 	struct radeonfb_info *rinfo;
+	struct fb_info *fb_info;
 	struct radeon_chip_info *rci = &radeon_chip_info[ent->driver_data];
 	u32 tmp;
 	int i, j;
@@ -1640,6 +1645,7 @@ static int radeonfb_pci_register (struct
 
 	memset (rinfo, 0, sizeof (struct radeonfb_info));
 
+	fb_info = (struct fb_info *)rinfo;
 	rinfo->pdev = pdev;
 	strncpy(rinfo->name, rci->name, 16);
 	rinfo->arch = rci->arch;
@@ -1824,8 +1830,16 @@ static int radeonfb_pci_register (struct
 		}
 	}
 
-	rinfo->fb_base = (unsigned long) ioremap (rinfo->fb_base_phys,
-				  		  rinfo->video_ram);
+	fb_info->mapped_vram = min_t(unsigned int, MAX_MAPPED_VRAM, rinfo->video_ram);
+	do {
+		rinfo->fb_base = (unsigned long) ioremap (rinfo->fb_base_phys,
+				  		  fb_info->mapped_vram);
+		if (rinfo->fb_base)
+			break;
+
+		fb_info->mapped_vram /= 2;
+	} while(fb_info->mapped_vram > MIN_MAPPED_VRAM);
+	
 	if (!rinfo->fb_base) {
 		printk ("radeonfb: cannot map FB\n");
 		iounmap ((void*)rinfo->mmio_base);
@@ -1836,6 +1850,7 @@ static int radeonfb_pci_register (struct
 		kfree (rinfo);
 		return -ENODEV;
 	}
+	RTRACE(KERN_INFO "radeonfb: mapped %dk videoram\n", fb_info->mapped_vram/1024);
 
 	/* currcon not yet configured, will be set by first switch */
 	rinfo->currcon = -1;
@@ -2199,13 +2214,14 @@ static int radeonfb_do_maximize(struct r
                 {-1, -1}
         };
         int i;
+	struct fb_info *fb_info = (struct fb_info *)rinfo;
                 
         /* use highest possible virtual resolution */
         if (v->xres_virtual == -1 && v->yres_virtual == -1) {
                 printk("radeonfb: using max available virtual resolution\n");
                 for (i=0; modes[i].xres != -1; i++) {
                         if (modes[i].xres * nom / den * modes[i].yres <
-                            rinfo->video_ram / 2)
+                            fb_info->mapped_vram / 2)
                                 break;
                 }
                 if (modes[i].xres == -1) {
@@ -2218,15 +2234,15 @@ static int radeonfb_do_maximize(struct r
                 printk("radeonfb: virtual resolution set to max of %dx%d\n",
                         v->xres_virtual, v->yres_virtual);
         } else if (v->xres_virtual == -1) {
-                v->xres_virtual = (rinfo->video_ram * den /   
+                v->xres_virtual = (fb_info->mapped_vram * den /   
                                 (nom * v->yres_virtual * 2)) & ~15;
         } else if (v->yres_virtual == -1) {
                 v->xres_virtual = (v->xres_virtual + 15) & ~15;
-                v->yres_virtual = rinfo->video_ram * den /
+                v->yres_virtual = fb_info->mapped_vram * den /
                         (nom * v->xres_virtual *2);
         } else {
                 if (v->xres_virtual * nom / den * v->yres_virtual >
-                        rinfo->video_ram) {
+                        fb_info->mapped_vram) {
                         return -EINVAL;
                 }
         }
@@ -2430,6 +2446,9 @@ try_again:
                         return -EINVAL;
         }
 
+	if (((v.xres_virtual * v.yres_virtual * nom) / den) > info->mapped_vram)
+		return -EINVAL;
+
         if (radeonfb_do_maximize(rinfo, var, &v, nom, den) < 0)
                 return -EINVAL;  
                 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/binfmt_aout.c linux-2.4.29-pre3/fs/binfmt_aout.c
--- linux-2.4.28/fs/binfmt_aout.c	2001-11-03 01:39:20.000000000 +0000
+++ linux-2.4.29-pre3/fs/binfmt_aout.c	2004-12-22 16:05:55.310010928 +0000
@@ -39,13 +39,18 @@ static struct linux_binfmt aout_format =
 	NULL, THIS_MODULE, load_aout_binary, load_aout_library, aout_core_dump, PAGE_SIZE
 };
 
-static void set_brk(unsigned long start, unsigned long end)
+#define BAD_ADDR(x)	((unsigned long)(x) >= TASK_SIZE)
+
+static int set_brk(unsigned long start, unsigned long end)
 {
 	start = PAGE_ALIGN(start);
 	end = PAGE_ALIGN(end);
-	if (end <= start)
-		return;
-	do_brk(start, end - start);
+	if (end > start) {
+		unsigned long addr = do_brk(start, end - start);
+		if (BAD_ADDR(addr))
+			return addr;
+	}
+	return 0;
 }
 
 /*
@@ -405,7 +410,11 @@ static int load_aout_binary(struct linux
 beyond_if:
 	set_binfmt(&aout_format);
 
-	set_brk(current->mm->start_brk, current->mm->brk);
+	retval = set_brk(current->mm->start_brk, current->mm->brk);
+	if (retval < 0) {
+		send_sig(SIGKILL, current, 0);
+		return retval;
+	}
 
 	retval = setup_arg_pages(bprm); 
 	if (retval < 0) { 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/binfmt_elf.c linux-2.4.29-pre3/fs/binfmt_elf.c
--- linux-2.4.28/fs/binfmt_elf.c	2004-12-22 16:17:18.969078952 +0000
+++ linux-2.4.29-pre3/fs/binfmt_elf.c	2004-12-22 16:06:36.686720712 +0000
@@ -79,13 +79,17 @@ static struct linux_binfmt elf_format = 
 
 #define BAD_ADDR(x)	((unsigned long)(x) > TASK_SIZE)
 
-static void set_brk(unsigned long start, unsigned long end)
+static int set_brk(unsigned long start, unsigned long end)
 {
 	start = ELF_PAGEALIGN(start);
 	end = ELF_PAGEALIGN(end);
-	if (end <= start)
-		return;
-	do_brk(start, end - start);
+	if (end > start) {
+		unsigned long addr = do_brk(start, end - start);
+		if (BAD_ADDR(addr))
+			return addr;
+	}
+	current->mm->start_brk = current->mm->brk = end;
+	return 0;
 }
 
 
@@ -331,6 +335,18 @@ static unsigned long load_elf_interp(str
 	    }
 
 	    /*
+	     * Check to see if the section's size will overflow the
+	     * allowed task size. Note that p_filesz must always be
+	     * <= p_memsize so it is only necessary to check p_memsz.
+	     */
+	    k = load_addr + eppnt->p_vaddr;
+	    if (k > TASK_SIZE || eppnt->p_filesz > eppnt->p_memsz ||
+		eppnt->p_memsz > TASK_SIZE || TASK_SIZE - eppnt->p_memsz < k) {
+	        error = -ENOMEM;
+		goto out_close;
+	    }
+
+	    /*
 	     * Find the end of the file mapping for this phdr, and keep
 	     * track of the largest address we see for this.
 	     */
@@ -360,10 +376,19 @@ static unsigned long load_elf_interp(str
 	elf_bss = ELF_PAGESTART(elf_bss + ELF_MIN_ALIGN - 1);	/* What we have mapped so far */
 
 	/* Map the last of the bss segment */
-	if (last_bss > elf_bss)
-		do_brk(elf_bss, last_bss - elf_bss);
+	if (last_bss > elf_bss) {
+		error = do_brk(elf_bss, last_bss - elf_bss);
+		if (BAD_ADDR(error))
+			goto out_close;
+	}
 
 	*interp_load_addr = load_addr;
+	/*
+	 * XXX: is everything deallocated properly if this happens
+	 * to be ~0UL (that is, we succeeded, but the header is broken
+	 * and thus the caller will think that we failed)? We'd better
+	 * switch to out-of-band error reporting.
+	 */
 	error = ((unsigned long) interp_elf_ex->e_entry) + load_addr;
 
 out_close:
@@ -464,12 +489,13 @@ static int load_elf_binary(struct linux_
 
 	/* Now read in all of the header information */
 
-	retval = -ENOMEM;
 	if (elf_ex.e_phentsize != sizeof(struct elf_phdr))
 		goto out;
-	if (elf_ex.e_phnum > 65536U / sizeof(struct elf_phdr))
+	if (elf_ex.e_phnum < 1 ||
+	    elf_ex.e_phnum > 65536U / sizeof(struct elf_phdr))
 		goto out;
 	size = elf_ex.e_phnum * sizeof(struct elf_phdr);
+	retval = -ENOMEM;
 	elf_phdata = (struct elf_phdr *) kmalloc(size, GFP_KERNEL);
 	if (!elf_phdata)
 		goto out;
@@ -515,10 +541,12 @@ static int load_elf_binary(struct linux_
 			 * is an a.out format binary
 			 */
 
-			retval = -ENOMEM;
+			retval = -ENOEXEC;
 			if (elf_ppnt->p_filesz > PATH_MAX || 
-			    elf_ppnt->p_filesz == 0)
+			    elf_ppnt->p_filesz < 2)
 				goto out_free_file;
+
+			retval = -ENOMEM;
 			elf_interpreter = (char *) kmalloc(elf_ppnt->p_filesz,
 							   GFP_KERNEL);
 			if (!elf_interpreter)
@@ -533,7 +561,7 @@ static int load_elf_binary(struct linux_
 				goto out_free_interp;
 			}
 			/* make sure path is NULL terminated */
-			retval = -EINVAL;
+			retval = -ENOEXEC;
 			if (elf_interpreter[elf_ppnt->p_filesz - 1] != '\0')
 				goto out_free_interp;
 
@@ -670,7 +698,12 @@ static int load_elf_binary(struct linux_
 			/* There was a PT_LOAD segment with p_memsz > p_filesz
 			   before this one. Map anonymous pages, if needed,
 			   and clear the area.  */
-			set_brk (elf_bss + load_bias, elf_brk + load_bias);
+			retval = set_brk (elf_bss + load_bias,
+					  elf_brk + load_bias);
+			if (retval) {
+				send_sig(SIGKILL, current, 0);
+				goto out_free_dentry;
+			}
 			nbyte = ELF_PAGEOFFSET(elf_bss);
 			if (nbyte) {
 				nbyte = ELF_MIN_ALIGN - nbyte;
@@ -716,6 +749,19 @@ static int load_elf_binary(struct linux_
 		if (k < start_code) start_code = k;
 		if (start_data < k) start_data = k;
 
+		/*
+		 * Check to see if the section's size will overflow the
+		 * allowed task size. Note that p_filesz must always be
+		 * <= p_memsz so it is only necessary to check p_memsz.
+		 */
+		if (k > TASK_SIZE || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
+		    elf_ppnt->p_memsz > TASK_SIZE ||
+		    TASK_SIZE - elf_ppnt->p_memsz < k) {
+			/* set_brk can never work.  Avoid overflows.  */
+			send_sig(SIGKILL, current, 0);
+			goto out_free_dentry;
+		}
+
 		k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
 
 		if (k > elf_bss)
@@ -737,6 +783,18 @@ static int load_elf_binary(struct linux_
 	start_data += load_bias;
 	end_data += load_bias;
 
+	/* Calling set_brk effectively mmaps the pages that we need
+	 * for the bss and break sections.  We must do this before
+	 * mapping in the interpreter, to make sure it doesn't wind
+	 * up getting placed where the bss needs to go.
+	 */
+	retval = set_brk(elf_bss, elf_brk);
+	if (retval) {
+		send_sig(SIGKILL, current, 0);
+		goto out_free_dentry;
+	}
+	padzero(elf_bss);
+
 	if (elf_interpreter) {
 		if (interpreter_type == INTERPRETER_AOUT)
 			elf_entry = load_aout_interp(&interp_ex,
@@ -746,8 +804,9 @@ static int load_elf_binary(struct linux_
 						    interpreter,
 						    &interp_load_addr);
 		if (BAD_ADDR(elf_entry)) {
-			printk(KERN_ERR "Unable to load interpreter\n");
-			send_sig(SIGSEGV, current, 0);
+			printk(KERN_ERR "Unable to load interpreter %.128s\n",
+				elf_interpreter);
+			force_sig(SIGSEGV, current);
 			retval = -ENOEXEC; /* Nobody gets to see this, but.. */
 			goto out_free_dentry;
 		}
@@ -785,13 +844,6 @@ static int load_elf_binary(struct linux_
 	current->mm->end_data = end_data;
 	current->mm->start_stack = bprm->p;
 
-	/* Calling set_brk effectively mmaps the pages that we need
-	 * for the bss and break sections
-	 */
-	set_brk(elf_bss, elf_brk);
-
-	padzero(elf_bss);
-
 #if 0
 	printk("(start_brk) %lx\n" , (long) current->mm->start_brk);
 	printk("(end_code) %lx\n" , (long) current->mm->end_code);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/dquot.c linux-2.4.29-pre3/fs/dquot.c
--- linux-2.4.28/fs/dquot.c	2004-08-07 23:26:05.000000000 +0000
+++ linux-2.4.29-pre3/fs/dquot.c	2004-12-22 16:07:10.798534928 +0000
@@ -794,8 +794,13 @@ static inline void dquot_decr_space(stru
 	mark_dquot_dirty(dquot);
 }
 
+static int flag_print_warnings = 1;
+
 static inline int need_print_warning(struct dquot *dquot, int flag)
 {
+	if (!flag_print_warnings)
+		return 0;
+
 	switch (dquot->dq_type) {
 		case USRQUOTA:
 			return current->fsuid == dquot->dq_id && !(dquot->dq_flags & flag);
@@ -1498,6 +1503,7 @@ static ctl_table fs_dqstats_table[] = {
 	{FS_DQ_ALLOCATED, "allocated_dquots", &dqstats.allocated_dquots, sizeof(int), 0444, NULL, &proc_dointvec},
 	{FS_DQ_FREE, "free_dquots", &dqstats.free_dquots, sizeof(int), 0444, NULL, &proc_dointvec},
 	{FS_DQ_SYNCS, "syncs", &dqstats.syncs, sizeof(int), 0444, NULL, &proc_dointvec},
+	{FS_DQ_WARNINGS, "warnings", &flag_print_warnings, sizeof(int), 0644, NULL, &proc_dointvec},
 	{},
 };
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/exec.c linux-2.4.29-pre3/fs/exec.c
--- linux-2.4.28/fs/exec.c	2004-02-18 13:36:31.000000000 +0000
+++ linux-2.4.29-pre3/fs/exec.c	2004-12-22 16:06:25.996345896 +0000
@@ -327,7 +327,7 @@ int setup_arg_pages(struct linux_binprm 
 {
 	unsigned long stack_base;
 	struct vm_area_struct *mpnt;
-	int i;
+	int i, ret;
 
 	stack_base = STACK_TOP - MAX_ARG_PAGES*PAGE_SIZE;
 
@@ -351,7 +351,11 @@ int setup_arg_pages(struct linux_binprm 
 		mpnt->vm_pgoff = 0;
 		mpnt->vm_file = NULL;
 		mpnt->vm_private_data = (void *) 0;
-		insert_vm_struct(current->mm, mpnt);
+		if ((ret = insert_vm_struct(current->mm, mpnt))) {
+			up_write(&current->mm->mmap_sem);
+			kmem_cache_free(vm_area_cachep, mpnt);
+			return ret;
+		}
 		current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
 	} 
 
@@ -563,12 +567,29 @@ static inline void de_thread(struct task
 	tsk->tgid = tsk->pid;
 }
 
+void get_task_comm(char *buf, struct task_struct *tsk)
+{
+	/* buf must be at least sizeof(tsk->comm) in size */
+	task_lock(tsk);
+	memcpy(buf, tsk->comm, sizeof(tsk->comm));
+	task_unlock(tsk);
+}
+
+void set_task_comm(struct task_struct *tsk, char *buf)
+{
+	task_lock(tsk);
+	strncpy(tsk->comm, buf, sizeof(tsk->comm));
+	tsk->comm[sizeof(tsk->comm)-1]='\0';
+	task_unlock(tsk);
+}
+
 int flush_old_exec(struct linux_binprm * bprm)
 {
 	char * name;
 	int i, ch, retval;
 	struct signal_struct * oldsig;
 	struct files_struct * files;
+	char tcomm[sizeof(current->comm)];
 
 	/*
 	 * Make sure we have a private signal table
@@ -610,10 +631,11 @@ int flush_old_exec(struct linux_binprm *
 		if (ch == '/')
 			i = 0;
 		else
-			if (i < 15)
-				current->comm[i++] = ch;
+			if (i < (sizeof(tcomm) - 1))
+				tcomm[i++] = ch;
 	}
-	current->comm[i] = '\0';
+	tcomm[i] = '\0';
+	set_task_comm(current, tcomm);
 
 	flush_thread();
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/intermezzo/cache.c linux-2.4.29-pre3/fs/intermezzo/cache.c
--- linux-2.4.28/fs/intermezzo/cache.c	2004-12-22 16:17:19.066064208 +0000
+++ linux-2.4.29-pre3/fs/intermezzo/cache.c	2004-12-22 16:06:30.250699136 +0000
@@ -163,6 +163,9 @@ inline void presto_free_cache(struct pre
                 cache->cache_sb->s_root->d_fsdata = NULL;
         }
 
+		if (cache->cache_type)
+				PRESTO_FREE(cache->cache_type, strlen(cache->cache_type) + 1 );
+
         PRESTO_FREE(cache, sizeof(struct presto_cache));
 }
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/intermezzo/dcache.c linux-2.4.29-pre3/fs/intermezzo/dcache.c
--- linux-2.4.28/fs/intermezzo/dcache.c	2002-11-28 23:53:15.000000000 +0000
+++ linux-2.4.29-pre3/fs/intermezzo/dcache.c	2004-12-22 16:07:31.914324840 +0000
@@ -324,6 +324,11 @@ out_unlock:    
                         dentry, dentry->d_name.len, dentry->d_name.name, 
                         dentry->d_fsdata);
         unlock_kernel();
+
+        filter_setup_dentry_ops(fset->fset_cache->cache_filter,
+                                dentry->d_op, &presto_dentry_ops);
+        dentry->d_op = filter_c2udops(fset->fset_cache->cache_filter);
+
         return error; 
 }
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/intermezzo/dir.c linux-2.4.29-pre3/fs/intermezzo/dir.c
--- linux-2.4.28/fs/intermezzo/dir.c	2002-11-28 23:53:15.000000000 +0000
+++ linux-2.4.29-pre3/fs/intermezzo/dir.c	2004-12-22 16:06:03.105825784 +0000
@@ -300,10 +300,7 @@ struct dentry *presto_lookup(struct inod
         /* some file systems have no read_inode: set methods here */
         if (dentry->d_inode)
                 presto_set_ops(dentry->d_inode, cache->cache_filter);
-
-        filter_setup_dentry_ops(cache->cache_filter,
-                                dentry->d_op, &presto_dentry_ops);
-        dentry->d_op = filter_c2udops(cache->cache_filter);
+		/* dentry->d_op is now hooked in dcache.c:presto_set_dd */
 
         /* In lookup we will tolerate EROFS return codes from presto_set_dd
          * to placate NFS. EROFS indicates that a fileset was not found but
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/intermezzo/fileset.c linux-2.4.29-pre3/fs/intermezzo/fileset.c
--- linux-2.4.28/fs/intermezzo/fileset.c	2002-11-28 23:53:15.000000000 +0000
+++ linux-2.4.29-pre3/fs/intermezzo/fileset.c	2004-12-22 16:06:58.450412128 +0000
@@ -159,7 +159,7 @@ static struct file *_izo_fset_open(char 
                 CDEBUG(D_INODE, "Error %d\n", error);
         }
 
-        PRESTO_FREE(path, strlen(path));
+        PRESTO_FREE(path, strlen(path)+1);
 
         EXIT;
         return f;
@@ -259,6 +259,7 @@ int presto_set_fsetroot(struct dentry *i
                 error = -ENOMEM;
                 goto out_free;
         }
+		
         presto_d2d(dentry)->dd_fset = fset;
         list_add(&fset->fset_list, &cache->cache_fset_list);
 
@@ -343,6 +344,7 @@ static int izo_cleanup_fset(struct prest
         dput(fset->fset_dentry);
         mntput(fset->fset_mnt);
 
+		izo_rep_cache_clean(fset);
         PRESTO_FREE(fset->fset_name, strlen(fset->fset_name) + 1);
         PRESTO_FREE(fset->fset_reint_buf, 64 * 1024);
         PRESTO_FREE(fset, sizeof(*fset));
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/intermezzo/journal_xfs.c linux-2.4.29-pre3/fs/intermezzo/journal_xfs.c
--- linux-2.4.28/fs/intermezzo/journal_xfs.c	2002-11-28 23:53:15.000000000 +0000
+++ linux-2.4.29-pre3/fs/intermezzo/journal_xfs.c	2004-12-22 16:07:21.990833440 +0000
@@ -58,7 +58,7 @@ static unsigned long presto_xfs_freespac
         VFS_STATVFS(vfsp, &stat, NULL, rc);
         avail = statp.f_bfree;
 
-        return sbp->sb_fdblocks;; 
+        return sbp->sb_fdblocks;
 #endif
         return 0x0fffffff;
 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/intermezzo/methods.c linux-2.4.29-pre3/fs/intermezzo/methods.c
--- linux-2.4.28/fs/intermezzo/methods.c	2002-11-28 23:53:15.000000000 +0000
+++ linux-2.4.29-pre3/fs/intermezzo/methods.c	2004-12-22 16:07:40.165070536 +0000
@@ -254,8 +254,8 @@ struct filter_fs *filter_get_filter_fs(c
         if (ops == NULL) {
                 CERROR("prepare to die: unrecognized cache type for Filter\n");
         }
-        return ops;
         FEXIT;
+        return ops;
 }
 
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/intermezzo/psdev.c linux-2.4.29-pre3/fs/intermezzo/psdev.c
--- linux-2.4.28/fs/intermezzo/psdev.c	2002-11-28 23:53:15.000000000 +0000
+++ linux-2.4.29-pre3/fs/intermezzo/psdev.c	2004-12-22 16:06:20.577169736 +0000
@@ -102,8 +102,7 @@ int izo_psdev_setpid(int minor)
                 struct list_head *lh;
                 struct upc_req *req;
                 CERROR("WARNING: setpid & processing not empty!\n");
-                lh = &channel->uc_processing;
-                while ( (lh = lh->next) != &channel->uc_processing) {
+		list_for_each(lh, &channel->uc_processing) {
                         req = list_entry(lh, struct upc_req, rq_chain);
                         /* freeing of req and data is done by the sleeper */
                         wake_up(&req->rq_sleep);
@@ -208,8 +207,7 @@ static ssize_t presto_psdev_write(struct
 
         spin_lock(&channel->uc_lock); 
         /* Look for the message on the processing queue. */
-        lh  = &channel->uc_processing;
-        while ( (lh = lh->next) != &channel->uc_processing ) {
+	list_for_each(lh, &channel->uc_processing) {
                 tmp = list_entry(lh, struct upc_req , rq_chain);
                 if (tmp->rq_unique == hdr.unique) {
                         req = tmp;
@@ -340,8 +338,7 @@ static int presto_psdev_release(struct i
         /* Wake up clients so they can return. */
         CDEBUG(D_PSDEV, "Wake up clients sleeping for pending.\n");
         spin_lock(&channel->uc_lock); 
-        lh = &channel->uc_pending;
-        while ( (lh = lh->next) != &channel->uc_pending) {
+	list_for_each(lh, &channel->uc_pending) {
                 req = list_entry(lh, struct upc_req, rq_chain);
 
                 /* Async requests stay around for a new lento */
@@ -354,8 +351,7 @@ static int presto_psdev_release(struct i
         }
 
         CDEBUG(D_PSDEV, "Wake up clients sleeping for processing\n");
-        lh = &channel->uc_processing;
-        while ( (lh = lh->next) != &channel->uc_processing) {
+	list_for_each(lh, &channel->uc_processing) {
                 req = list_entry(lh, struct upc_req, rq_chain);
                 /* freeing of req and data is done by the sleeper */
                 req->rq_flags |= REQ_DEAD; 
@@ -421,7 +417,7 @@ void presto_psdev_cleanup(void)
 
         for ( i = 0 ; i < MAX_CHANNEL ; i++ ) {
                 struct upc_channel *channel = &(izo_channels[i]);
-                struct list_head *lh;
+                struct list_head *lh, *next;
 
                 spin_lock(&channel->uc_lock); 
                 if ( ! list_empty(&channel->uc_pending)) { 
@@ -433,12 +429,10 @@ void presto_psdev_cleanup(void)
                 if ( ! list_empty(&channel->uc_cache_list)) { 
                         CERROR("Weird, tell Peter: module cleanup and cache listnot empty dev %d\n", i);
                 }
-                lh = channel->uc_pending.next;
-                while ( lh != &channel->uc_pending) {
+		list_for_each_safe(lh, next, &channel->uc_pending) {
                         struct upc_req *req;
 
                         req = list_entry(lh, struct upc_req, rq_chain);
-                        lh = lh->next;
                         if ( req->rq_flags & REQ_ASYNC ) {
                                 list_del(&(req->rq_chain));
                                 CDEBUG(D_UPCALL, "free pending upcall type %d\n",
@@ -450,8 +444,7 @@ void presto_psdev_cleanup(void)
                                 wake_up(&req->rq_sleep);
                         }
                 }
-                lh = &channel->uc_processing;
-                while ( (lh = lh->next) != &channel->uc_processing ) {
+		list_for_each(lh, &channel->uc_processing) {
                         struct upc_req *req;
                         req = list_entry(lh, struct upc_req, rq_chain);
                         list_del(&(req->rq_chain));
@@ -564,6 +557,10 @@ int izo_upc_upcall(int minor, int *size,
         buffer->u_uniq = req->rq_unique;
         buffer->u_async = async;
 
+        /* Remove potential datarace possibility*/
+        if ( async ) 
+                req->rq_flags = REQ_ASYNC;
+
         spin_lock(&channel->uc_lock); 
         /* Append msg to pending queue and poke Lento. */
         list_add(&req->rq_chain, channel->uc_pending.prev);
@@ -576,7 +573,7 @@ int izo_upc_upcall(int minor, int *size,
 
         if ( async ) {
                 /* req, rq_data are freed in presto_psdev_read for async */
-                req->rq_flags = REQ_ASYNC;
+                /* req->rq_flags = REQ_ASYNC;*/
                 EXIT;
                 return 0;
         }
@@ -647,5 +644,6 @@ int izo_upc_upcall(int minor, int *size,
 exit_req:
         PRESTO_FREE(req, sizeof(struct upc_req));
 exit_buf:
+        PRESTO_FREE(buffer,*size);
         return error;
 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/intermezzo/replicator.c linux-2.4.29-pre3/fs/intermezzo/replicator.c
--- linux-2.4.28/fs/intermezzo/replicator.c	2002-11-28 23:53:15.000000000 +0000
+++ linux-2.4.29-pre3/fs/intermezzo/replicator.c	2004-12-22 16:05:32.106538392 +0000
@@ -70,7 +70,7 @@ izo_rep_hash(struct list_head *cache, ch
         return &cache[(RCACHE_MASK & uuid[1])];
 }
 
-static void
+void
 izo_rep_cache_clean(struct presto_file_set *fset)
 {
 	int i;
@@ -80,28 +80,25 @@ izo_rep_cache_clean(struct presto_file_s
         if (fset->fset_clients == NULL)
 		return;
         for (i = 0; i < RCACHE_SIZE; i++) {
-		tmp = bucket = &fset->fset_clients[i];
 
-		tmp = tmp->next;
-                while (tmp != bucket) {
-			struct izo_offset_rec *offrec;
-			tmp = tmp->next;
-			list_del(tmp);
-			offrec = list_entry(tmp, struct izo_offset_rec,
-					    or_list);
-			PRESTO_FREE(offrec, sizeof(struct izo_offset_rec));
+				list_for_each_safe(tmp,bucket,&fset->fset_clients[i])
+				{
+						struct izo_offset_rec *offrec;
+						list_del(tmp);
+						offrec = list_entry(tmp, struct izo_offset_rec,or_list);
+						PRESTO_FREE(offrec, sizeof(struct izo_offset_rec)); 
+				}
 		}
-	}
+		PRESTO_FREE(fset->fset_clients,sizeof(struct list_head) * RCACHE_SIZE);
 }
 
 struct izo_offset_rec *
 izo_rep_cache_find(struct presto_file_set *fset, char *uuid)
 {
-	struct list_head *buck = izo_rep_hash(fset->fset_clients, uuid);
-	struct list_head *tmp = buck;
+	struct list_head *tmp, *buck = izo_rep_hash(fset->fset_clients, uuid);
         struct izo_offset_rec *rec = NULL;
 
-        while ( (tmp = tmp->next) != buck ) {
+	list_for_each(tmp, buck) {
 		rec = list_entry(tmp, struct izo_offset_rec, or_list);
                 if ( memcmp(rec->or_uuid, uuid, sizeof(rec->or_uuid)) == 0 )
 			return rec;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/intermezzo/super.c linux-2.4.29-pre3/fs/intermezzo/super.c
--- linux-2.4.28/fs/intermezzo/super.c	2002-11-28 23:53:15.000000000 +0000
+++ linux-2.4.29-pre3/fs/intermezzo/super.c	2004-12-22 16:07:51.307376648 +0000
@@ -23,8 +23,8 @@
  *  presto's super.c
  */
 
-static char rcsid[] __attribute ((unused)) = "$Id: super.c,v 1.41 2002/10/03 03:50:49 rread Exp $";
-#define INTERMEZZO_VERSION "$Revision: 1.41 $"
+static char rcsid[] __attribute ((unused)) = "$Id: super.c,v 1.42 2003/09/30 15:51:52 sunsetyang Exp $";
+#define INTERMEZZO_VERSION "$Revision: 1.42 $"
 
 #include <stdarg.h>
 
@@ -172,6 +172,7 @@ static int presto_set_channel(struct pre
                 minor = izo_psdev_get_free_channel();
         } else {
                 minor = simple_strtoul(channel, NULL, 0); 
+				PRESTO_FREE(channel, strlen(channel) + 1);
         }
         if (minor < 0 || minor >= MAX_CHANNEL) { 
                 CERROR("all channels in use or channel too large %d\n", 
@@ -287,6 +288,9 @@ struct super_block * presto_read_super(s
         presto_cache_add(cache, sb->s_dev);
         err = izo_prepare_fileset(sb->s_root, fileset); 
 
+        if (fileset)
+                PRESTO_FREE(fileset, strlen(fileset) + 1);
+
         filter_setup_journal_ops(cache->cache_filter, cache->cache_type); 
 
         /* make sure we have our own super operations: sb
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/intermezzo/vfs.c linux-2.4.29-pre3/fs/intermezzo/vfs.c
--- linux-2.4.28/fs/intermezzo/vfs.c	2003-06-13 14:51:37.000000000 +0000
+++ linux-2.4.29-pre3/fs/intermezzo/vfs.c	2004-12-22 16:06:19.694303952 +0000
@@ -2194,6 +2194,7 @@ again:  /* look the named file or a pare
         if ( error && error != -ENOENT ) {
                 EXIT;
                 unlock_kernel();
+                putname(tmp);
                 return error;
         } 
         if (error == -ENOENT)
@@ -2240,7 +2241,7 @@ again:  /* look the named file or a pare
         fd = get_unused_fd();
         if (fd < 0) {
                 EXIT;
-                goto cleanup_dput;
+                goto exit;
         }
 
         {
@@ -2250,10 +2251,9 @@ again:  /* look the named file or a pare
                 if (IS_ERR(f)) {
                         put_unused_fd(fd);
                         fd = error;
-                        EXIT;
-                        goto cleanup_dput;
+                } else {
+                        fd_install(fd, f);
                 }
-                fd_install(fd, f);
         }
         /* end of code that might be replaced by open_dentry */
 
@@ -2263,10 +2263,6 @@ exit:
         path_release(&nd);
         putname(tmp);
         return fd;
-
-cleanup_dput:
-        putname(&nd);
-        goto exit;
 }
 
 #ifdef CONFIG_FS_EXT_ATTR
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/isofs/inode.c linux-2.4.29-pre3/fs/isofs/inode.c
--- linux-2.4.28/fs/isofs/inode.c	2002-11-28 23:53:15.000000000 +0000
+++ linux-2.4.29-pre3/fs/isofs/inode.c	2004-12-22 16:07:42.997639920 +0000
@@ -34,11 +34,6 @@
 
 #include "zisofs.h"
 
-/*
- * We have no support for "multi volume" CDs, but more and more disks carry
- * wrong information within the volume descriptors.
- */
-#define IGNORE_WRONG_MULTI_VOLUME_SPECS
 #define BEQUIET
 
 #ifdef LEAK_CHECK
@@ -489,19 +484,6 @@ static struct super_block *isofs_read_su
 	if (!parse_options((char *) data, &opt))
 		goto out_unlock;
 
-#if 0
-	printk("map = %c\n", opt.map);
-	printk("rock = %c\n", opt.rock);
-	printk("joliet = %c\n", opt.joliet);
-	printk("check = %c\n", opt.check);
-	printk("cruft = %c\n", opt.cruft);
-	printk("unhide = %c\n", opt.unhide);
-	printk("blocksize = %d\n", opt.blocksize);
-	printk("gid = %d\n", opt.gid);
-	printk("uid = %d\n", opt.uid);
-	printk("iocharset = %s\n", opt.iocharset);
-#endif
-
 	/*
 	 * First of all, get the hardware blocksize for this device.
 	 * If we don't know what it is, or the hardware blocksize is
@@ -623,19 +605,11 @@ root_found:
 
 	if(high_sierra){
 	  rootp = (struct iso_directory_record *) h_pri->root_directory_record;
-#ifndef IGNORE_WRONG_MULTI_VOLUME_SPECS
-	  if (isonum_723 (h_pri->volume_set_size) != 1)
-		goto out_no_support;
-#endif /* IGNORE_WRONG_MULTI_VOLUME_SPECS */
 	  s->u.isofs_sb.s_nzones = isonum_733 (h_pri->volume_space_size);
 	  s->u.isofs_sb.s_log_zone_size = isonum_723 (h_pri->logical_block_size);
 	  s->u.isofs_sb.s_max_size = isonum_733(h_pri->volume_space_size);
 	} else {
 	  rootp = (struct iso_directory_record *) pri->root_directory_record;
-#ifndef IGNORE_WRONG_MULTI_VOLUME_SPECS
-	  if (isonum_723 (pri->volume_set_size) != 1)
-		goto out_no_support;
-#endif /* IGNORE_WRONG_MULTI_VOLUME_SPECS */
 	  s->u.isofs_sb.s_nzones = isonum_733 (pri->volume_space_size);
 	  s->u.isofs_sb.s_log_zone_size = isonum_723 (pri->logical_block_size);
 	  s->u.isofs_sb.s_max_size = isonum_733(pri->volume_space_size);
@@ -855,11 +829,6 @@ out_bad_size:
 	printk(KERN_WARNING "Logical zone size(%d) < hardware blocksize(%u)\n",
 		orig_zonesize, blocksize);
 	goto out_freebh;
-#ifndef IGNORE_WRONG_MULTI_VOLUME_SPECS
-out_no_support:
-	printk(KERN_WARNING "Multi-volume disks not supported.\n");
-	goto out_freebh;
-#endif
 out_unknown_format:
 	if (!silent)
 		printk(KERN_WARNING "Unable to identify CD-ROM format.\n");
@@ -1212,30 +1181,13 @@ static void isofs_read_inode(struct inod
 	}
 
 	/*
-	 * The ISO-9660 filesystem only stores 32 bits for file size.
-	 * mkisofs handles files up to 2GB-2 = 2147483646 = 0x7FFFFFFE bytes
-	 * in size. This is according to the large file summit paper from 1996.
-	 * WARNING: ISO-9660 filesystems > 1 GB and even > 2 GB are fully
-	 *	    legal. Do not prevent to use DVD's schilling@fokus.gmd.de
-	 */
-	if ((inode->i_size < 0 || inode->i_size > 0x7FFFFFFE) &&
-	    inode->i_sb->u.isofs_sb.s_cruft == 'n') {
-		printk(KERN_WARNING "Warning: defective CD-ROM.  "
-		       "Enabling \"cruft\" mount option.\n");
-		inode->i_sb->u.isofs_sb.s_cruft = 'y';
-	}
-
-	/*
 	 * Some dipshit decided to store some other bit of information
-	 * in the high byte of the file length.  Catch this and holler.
-	 * WARNING: this will make it impossible for a file to be > 16MB
-	 * on the CDROM.
+	 * in the high byte of the file length.  Truncate in case
+	 * this CDROM was mounted with the cruft option.
 	 */
 
-	if (inode->i_sb->u.isofs_sb.s_cruft == 'y' &&
-	    inode->i_size & 0xff000000) {
+	if (inode->i_sb->u.isofs_sb.s_cruft == 'y')
 		inode->i_size &= 0x00ffffff;
-	}
 
 	if (de->interleave[0]) {
 		printk("Interleaved files not (yet) supported.\n");
@@ -1283,61 +1235,29 @@ static void isofs_read_inode(struct inod
 	/* get the volume sequence number */
 	volume_seq_no = isonum_723 (de->volume_sequence_number) ;
 
-    /*
-     * Multi volume means tagging a group of CDs with info in their headers.
-     * All CDs of a group must share the same vol set name and vol set size
-     * and have different vol set seq num. Deciding that data is wrong based
-     * in that three fields is wrong. The fields are informative, for
-     * cataloging purposes in a big jukebox, ie. Read sections 4.17, 4.18, 6.6
-     * of ftp://ftp.ecma.ch/ecma-st/Ecma-119.pdf (ECMA 119 2nd Ed = ISO 9660)
-     */
-#ifndef IGNORE_WRONG_MULTI_VOLUME_SPECS
-	/*
-	 * Disable checking if we see any volume number other than 0 or 1.
-	 * We could use the cruft option, but that has multiple purposes, one
-	 * of which is limiting the file size to 16Mb.  Thus we silently allow
-	 * volume numbers of 0 to go through without complaining.
-	 */
-	if (inode->i_sb->u.isofs_sb.s_cruft == 'n' &&
-	    (volume_seq_no != 0) && (volume_seq_no != 1)) {
-		printk(KERN_WARNING "Warning: defective CD-ROM "
-		       "(volume sequence number %d). "
-		       "Enabling \"cruft\" mount option.\n", volume_seq_no);
-		inode->i_sb->u.isofs_sb.s_cruft = 'y';
-	}
-#endif /*IGNORE_WRONG_MULTI_VOLUME_SPECS */
-
 	/* Install the inode operations vector */
-#ifndef IGNORE_WRONG_MULTI_VOLUME_SPECS
-	if (inode->i_sb->u.isofs_sb.s_cruft != 'y' &&
-	    (volume_seq_no != 0) && (volume_seq_no != 1)) {
-		printk(KERN_WARNING "Multi-volume CD somehow got mounted.\n");
-	} else
-#endif /*IGNORE_WRONG_MULTI_VOLUME_SPECS */
-	{
-		if (S_ISREG(inode->i_mode)) {
-			inode->i_fop = &generic_ro_fops;
-			switch ( inode->u.isofs_i.i_file_format ) {
+	if (S_ISREG(inode->i_mode)) {
+		inode->i_fop = &generic_ro_fops;
+		switch ( inode->u.isofs_i.i_file_format ) {
 #ifdef CONFIG_ZISOFS
-			case isofs_file_compressed:
-				inode->i_data.a_ops = &zisofs_aops;
-				break;
-#endif
-			default:
-				inode->i_data.a_ops = &isofs_aops;
-				break;
-			}
-		} else if (S_ISDIR(inode->i_mode)) {
-			inode->i_op = &isofs_dir_inode_operations;
-			inode->i_fop = &isofs_dir_operations;
-		} else if (S_ISLNK(inode->i_mode)) {
-			inode->i_op = &page_symlink_inode_operations;
-			inode->i_data.a_ops = &isofs_symlink_aops;
-		} else
-			/* XXX - parse_rock_ridge_inode() had already set i_rdev. */
-			init_special_inode(inode, inode->i_mode,
-					   kdev_t_to_nr(inode->i_rdev));
-	}
+		case isofs_file_compressed:
+			inode->i_data.a_ops = &zisofs_aops;
+			break;
+#endif
+		default:
+			inode->i_data.a_ops = &isofs_aops;
+			break;
+		}
+	} else if (S_ISDIR(inode->i_mode)) {
+		inode->i_op = &isofs_dir_inode_operations;
+		inode->i_fop = &isofs_dir_operations;
+	} else if (S_ISLNK(inode->i_mode)) {
+		inode->i_op = &page_symlink_inode_operations;
+		inode->i_data.a_ops = &isofs_symlink_aops;
+	} else
+		/* XXX - parse_rock_ridge_inode() had already set i_rdev. */
+		init_special_inode(inode, inode->i_mode,
+				   kdev_t_to_nr(inode->i_rdev));
  out:
 	if (tmpde)
 		kfree(tmpde);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/jfs/inode.c linux-2.4.29-pre3/fs/jfs/inode.c
--- linux-2.4.28/fs/jfs/inode.c	2004-08-07 23:26:05.000000000 +0000
+++ linux-2.4.29-pre3/fs/jfs/inode.c	2004-12-22 16:06:18.476489088 +0000
@@ -130,8 +130,7 @@ int jfs_commit_inode(struct inode *inode
 	 * Don't commit if inode has been committed since last being
 	 * marked dirty, or if it has been deleted.
 	 */
-	if (test_cflag(COMMIT_Nolink, inode) ||
-	    !test_cflag(COMMIT_Dirty, inode))
+	if (inode->i_nlink == 0 || !test_cflag(COMMIT_Dirty, inode))
 		return 0;
 
 	if (isReadOnly(inode)) {
@@ -149,7 +148,13 @@ int jfs_commit_inode(struct inode *inode
 
 	tid = txBegin(inode->i_sb, COMMIT_INODE);
 	down(&JFS_IP(inode)->commit_sem);
-	rc = txCommit(tid, 1, &inode, wait ? COMMIT_SYNC : 0);
+
+	/*
+	 * Retest inode state after taking commit_sem
+	 */
+	if (inode->i_nlink && test_cflag(COMMIT_Dirty, inode))
+		rc = txCommit(tid, 1, &inode, wait ? COMMIT_SYNC : 0);
+
 	txEnd(tid);
 	up(&JFS_IP(inode)->commit_sem);
 	return rc;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/jfs/jfs_imap.c linux-2.4.29-pre3/fs/jfs/jfs_imap.c
--- linux-2.4.28/fs/jfs/jfs_imap.c	2004-08-07 23:26:05.000000000 +0000
+++ linux-2.4.29-pre3/fs/jfs/jfs_imap.c	2004-12-22 16:06:40.037211360 +0000
@@ -3000,8 +3000,7 @@ int diExtendFS(struct inode *ipimap, str
 					goto nextiag;
 				}
 				hiagp = (struct iag *) hbp->data;
-				hiagp->inofreeback =
-				    le32_to_cpu(iagp->iagnum);
+				hiagp->inofreeback = iagp->iagnum;
 				iagp->inofreefwd = cpu_to_le32(head);
 				iagp->inofreeback = -1;
 				write_metapage(hbp);
@@ -3075,7 +3074,7 @@ static void duplicateIXtree(struct super
 		if (readSuper(sb, &bh))
 			return;
 		j_sb = (struct jfs_superblock *)bh->b_data;
-		j_sb->s_flag |= JFS_BAD_SAIT;
+		j_sb->s_flag |= cpu_to_le32(JFS_BAD_SAIT);
 
 		mark_buffer_dirty(bh);
 		ll_rw_block(WRITE, 1, &bh);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/jfs/jfs_logmgr.c linux-2.4.29-pre3/fs/jfs/jfs_logmgr.c
--- linux-2.4.28/fs/jfs/jfs_logmgr.c	2004-08-07 23:26:05.000000000 +0000
+++ linux-2.4.29-pre3/fs/jfs/jfs_logmgr.c	2004-12-22 16:07:51.937280888 +0000
@@ -1340,6 +1340,8 @@ int lmLogInit(struct jfs_log * log)
 	 *      unwind on error
 	 */
       errout30:		/* release log page */
+	log->wqueue = NULL;
+	bp->l_wqnext = NULL;
 	lbmFree(bp);
 
       errout20:		/* release log superblock */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/jfs/jfs_mount.c linux-2.4.29-pre3/fs/jfs/jfs_mount.c
--- linux-2.4.28/fs/jfs/jfs_mount.c	2004-12-22 16:17:19.152051136 +0000
+++ linux-2.4.29-pre3/fs/jfs/jfs_mount.c	2004-12-22 16:06:15.436951168 +0000
@@ -323,7 +323,7 @@ static int chkSuper(struct super_block *
 	 */
 	/* validate fs signature */
 	if (strncmp(j_sb->s_magic, JFS_MAGIC, 4) ||
-	    j_sb->s_version > cpu_to_le32(JFS_VERSION)) {
+	    le32_to_cpu(j_sb->s_version) > JFS_VERSION) {
 		rc = -EINVAL;
 		goto out;
 	}
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/jfs/jfs_xtree.c linux-2.4.29-pre3/fs/jfs/jfs_xtree.c
--- linux-2.4.28/fs/jfs/jfs_xtree.c	2004-08-07 23:26:06.000000000 +0000
+++ linux-2.4.29-pre3/fs/jfs/jfs_xtree.c	2004-12-22 16:07:48.182851648 +0000
@@ -1,5 +1,5 @@
 /*
- *   Copyright (C) International Business Machines Corp., 2000-2003
+ *   Copyright (C) International Business Machines Corp., 2000-2004
  *
  *   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
@@ -951,7 +951,7 @@ xtSplitUp(tid_t tid,
 
 	/* is inode xtree root extension/inline EA area free ? */
 	if ((sp->header.flag & BT_ROOT) && (!S_ISDIR(ip->i_mode)) &&
-	    (sp->header.maxentry < cpu_to_le16(XTROOTMAXSLOT)) &&
+	    (le16_to_cpu(sp->header.maxentry) < XTROOTMAXSLOT) &&
 	    (JFS_IP(ip)->mode2 & INLINEEA)) {
 		sp->header.maxentry = cpu_to_le16(XTROOTMAXSLOT);
 		JFS_IP(ip)->mode2 &= ~INLINEEA;
@@ -1595,7 +1595,6 @@ int xtExtend(tid_t tid,		/* transaction 
 	s64 xaddr;
 	struct tlock *tlck;
 	struct xtlock *xtlck = 0;
-	int rootsplit = 0;
 
 	jfs_info("xtExtend: nxoff:0x%lx nxlen:0x%x", (ulong) xoff, xlen);
 
@@ -1651,8 +1650,6 @@ int xtExtend(tid_t tid,		/* transaction 
 	 * The xtSplitUp() will insert the entry and unpin the leaf page.
 	 */
 	if (nextindex == le16_to_cpu(p->header.maxentry)) {
-		rootsplit = p->header.flag & BT_ROOT;
-
 		/* xtSpliUp() unpins leaf pages */
 		split.mp = mp;
 		split.index = index + 1;
@@ -1664,16 +1661,21 @@ int xtExtend(tid_t tid,		/* transaction 
 		if ((rc = xtSplitUp(tid, ip, &split, &btstack)))
 			return rc;
 
+		/* get back old page */
+		XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+		if (rc)
+			return rc;
 		/*
 		 * if leaf root has been split, original root has been
 		 * copied to new child page, i.e., original entry now
 		 * resides on the new child page;
 		 */
-		if (rootsplit) {
+		if (p->header.flag & BT_INTERNAL) {
 			ASSERT(p->header.nextindex ==
 			       cpu_to_le16(XTENTRYSTART + 1));
 			xad = &p->xad[XTENTRYSTART];
 			bn = addressXAD(xad);
+			XT_PUTPAGE(mp);
 
 			/* get new child page */
 			XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
@@ -1685,11 +1687,6 @@ int xtExtend(tid_t tid,		/* transaction 
 				tlck = txLock(tid, ip, mp, tlckXTREE|tlckGROW);
 				xtlck = (struct xtlock *) & tlck->lock;
 			}
-		} else {
-			/* get back old page */
-			XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
-			if (rc)
-				return rc;
 		}
 	}
 	/*
@@ -1763,7 +1760,6 @@ int xtTailgate(tid_t tid,		/* transactio
 	struct xtlock *xtlck = 0;
 	struct tlock *mtlck;
 	struct maplock *pxdlock;
-	int rootsplit = 0;
 
 /*
 printf("xtTailgate: nxoff:0x%lx nxlen:0x%x nxaddr:0x%lx\n",
@@ -1821,8 +1817,6 @@ printf("xtTailgate: xoff:0x%lx xlen:0x%x
 	 * The xtSplitUp() will insert the entry and unpin the leaf page.
 	 */
 	if (nextindex == le16_to_cpu(p->header.maxentry)) {
-		rootsplit = p->header.flag & BT_ROOT;
-
 		/* xtSpliUp() unpins leaf pages */
 		split.mp = mp;
 		split.index = index + 1;
@@ -1834,16 +1828,21 @@ printf("xtTailgate: xoff:0x%lx xlen:0x%x
 		if ((rc = xtSplitUp(tid, ip, &split, &btstack)))
 			return rc;
 
+		/* get back old page */
+		XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+		if (rc)
+			return rc;
 		/*
 		 * if leaf root has been split, original root has been
 		 * copied to new child page, i.e., original entry now
 		 * resides on the new child page;
 		 */
-		if (rootsplit) {
+		if (p->header.flag & BT_INTERNAL) {
 			ASSERT(p->header.nextindex ==
 			       cpu_to_le16(XTENTRYSTART + 1));
 			xad = &p->xad[XTENTRYSTART];
 			bn = addressXAD(xad);
+			XT_PUTPAGE(mp);
 
 			/* get new child page */
 			XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
@@ -1855,11 +1854,6 @@ printf("xtTailgate: xoff:0x%lx xlen:0x%x
 				tlck = txLock(tid, ip, mp, tlckXTREE|tlckGROW);
 				xtlck = (struct xtlock *) & tlck->lock;
 			}
-		} else {
-			/* get back old page */
-			XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
-			if (rc)
-				return rc;
 		}
 	}
 	/*
@@ -1949,7 +1943,7 @@ int xtUpdate(tid_t tid, struct inode *ip
 	s64 nxaddr, xaddr;
 	struct tlock *tlck;
 	struct xtlock *xtlck = 0;
-	int rootsplit = 0, newpage = 0;
+	int newpage = 0;
 
 	/* there must exist extent to be tailgated */
 	nxoff = offsetXAD(nxad);
@@ -2156,7 +2150,6 @@ int xtUpdate(tid_t tid, struct inode *ip
 
 	/* insert nXAD:recorded */
 	if (nextindex == le16_to_cpu(p->header.maxentry)) {
-		rootsplit = p->header.flag & BT_ROOT;
 
 		/* xtSpliUp() unpins leaf pages */
 		split.mp = mp;
@@ -2169,16 +2162,21 @@ int xtUpdate(tid_t tid, struct inode *ip
 		if ((rc = xtSplitUp(tid, ip, &split, &btstack)))
 			return rc;
 
+		/* get back old page */
+		XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+		if (rc)
+			return rc;
 		/*
 		 * if leaf root has been split, original root has been
 		 * copied to new child page, i.e., original entry now
 		 * resides on the new child page;
 		 */
-		if (rootsplit) {
+		if (p->header.flag & BT_INTERNAL) {
 			ASSERT(p->header.nextindex ==
 			       cpu_to_le16(XTENTRYSTART + 1));
 			xad = &p->xad[XTENTRYSTART];
 			bn = addressXAD(xad);
+			XT_PUTPAGE(mp);
 
 			/* get new child page */
 			XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
@@ -2191,11 +2189,6 @@ int xtUpdate(tid_t tid, struct inode *ip
 				xtlck = (struct xtlock *) & tlck->lock;
 			}
 		} else {
-			/* get back old page */
-			XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
-			if (rc)
-				return rc;
-
 			/* is nXAD on new page ? */
 			if (newindex >
 			    (le16_to_cpu(p->header.maxentry) >> 1)) {
@@ -2309,8 +2302,6 @@ int xtUpdate(tid_t tid, struct inode *ip
 	xlen = xlen - nxlen;
 	xaddr = xaddr + nxlen;
 	if (nextindex == le16_to_cpu(p->header.maxentry)) {
-		rootsplit = p->header.flag & BT_ROOT;
-
 /*
 printf("xtUpdate.updateLeft.split p:0x%p\n", p);
 */
@@ -2325,16 +2316,22 @@ printf("xtUpdate.updateLeft.split p:0x%p
 		if ((rc = xtSplitUp(tid, ip, &split, &btstack)))
 			return rc;
 
+		/* get back old page */
+		XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+		if (rc)
+			return rc;
+
 		/*
 		 * if leaf root has been split, original root has been
 		 * copied to new child page, i.e., original entry now
 		 * resides on the new child page;
 		 */
-		if (rootsplit) {
+		if (p->header.flag & BT_INTERNAL) {
 			ASSERT(p->header.nextindex ==
 			       cpu_to_le16(XTENTRYSTART + 1));
 			xad = &p->xad[XTENTRYSTART];
 			bn = addressXAD(xad);
+			XT_PUTPAGE(mp);
 
 			/* get new child page */
 			XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
@@ -2346,11 +2343,6 @@ printf("xtUpdate.updateLeft.split p:0x%p
 				tlck = txLock(tid, ip, mp, tlckXTREE|tlckGROW);
 				xtlck = (struct xtlock *) & tlck->lock;
 			}
-		} else {
-			/* get back old page */
-			XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
-			if (rc)
-				return rc;
 		}
 	} else {
 		/* if insert into middle, shift right remaining entries */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/namei.c linux-2.4.29-pre3/fs/namei.c
--- linux-2.4.28/fs/namei.c	2004-12-22 16:17:19.171048248 +0000
+++ linux-2.4.29-pre3/fs/namei.c	2004-12-22 16:06:21.890970008 +0000
@@ -326,7 +326,7 @@ static struct dentry * real_lookup(struc
 }
 
 /*
- * This limits recursive symlink follows to 8, while
+ * This limits recursive symlink follows to 5, while
  * limiting consecutive symlinks to 40.
  *
  * Without that kind of total limit, nasty chains of consecutive
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/nfs/dir.c linux-2.4.29-pre3/fs/nfs/dir.c
--- linux-2.4.28/fs/nfs/dir.c	2004-08-07 23:26:06.000000000 +0000
+++ linux-2.4.29-pre3/fs/nfs/dir.c	2004-12-22 16:06:42.041906600 +0000
@@ -999,7 +999,7 @@ static int nfs_rename(struct inode *old_
 	struct inode *old_inode = old_dentry->d_inode;
 	struct inode *new_inode = new_dentry->d_inode;
 	struct dentry *dentry = NULL, *rehash = NULL;
-	int error;
+	int error = -EBUSY;
 
 	/*
 	 * To prevent any new references to the target during the rename,
@@ -1025,12 +1025,6 @@ static int nfs_rename(struct inode *old_
 	 */
 	if (!new_inode)
 		goto go_ahead;
-	/* If target is a hard link to the source, then noop */
-	error = 0;
-	if (NFS_FILEID(new_inode) == NFS_FILEID(old_inode))
-		goto out;
-
-	error = -EBUSY;
 	if (S_ISDIR(new_inode->i_mode))
 		goto out;
 	else if (atomic_read(&new_dentry->d_count) > 1) {
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/nfs/unlink.c linux-2.4.29-pre3/fs/nfs/unlink.c
--- linux-2.4.28/fs/nfs/unlink.c	2004-12-22 16:17:19.205043080 +0000
+++ linux-2.4.29-pre3/fs/nfs/unlink.c	2004-12-22 16:07:41.368887528 +0000
@@ -12,7 +12,6 @@
 #include <linux/sunrpc/sched.h>
 #include <linux/sunrpc/clnt.h>
 #include <linux/nfs_fs.h>
-#include <linux/wait.h>
 
 
 struct nfs_unlinkdata {
@@ -22,9 +21,6 @@ struct nfs_unlinkdata {
 	struct rpc_task	task;
 	struct rpc_cred	*cred;
 	unsigned int	count;
-
-	wait_queue_head_t waitq;
-	int completed;
 };
 
 static struct nfs_unlinkdata	*nfs_deletes;
@@ -130,16 +126,13 @@ nfs_async_unlink_done(struct rpc_task *t
 	if (nfs_async_handle_jukebox(task))
 		return;
 	if (!dir)
-		goto out;
+		return;
 	dir_i = dir->d_inode;
 	nfs_zap_caches(dir_i);
 	NFS_PROTO(dir_i)->unlink_done(dir, &task->tk_msg);
 	put_rpccred(data->cred);
 	data->cred = NULL;
 	dput(dir);
-out:
-	data->completed = 1;
-	wake_up(&data->waitq);
 }
 
 /**
@@ -182,8 +175,6 @@ nfs_async_unlink(struct dentry *dentry)
 	nfs_deletes = data;
 	data->count = 1;
 
-	init_waitqueue_head(&data->waitq);
-
 	task = &data->task;
 	rpc_init_task(task, clnt, nfs_async_unlink_done , RPC_TASK_ASYNC);
 	task->tk_calldata = data;
@@ -221,10 +212,7 @@ nfs_complete_unlink(struct dentry *dentr
 	data->count++;
 	nfs_copy_dname(dentry, data);
 	dentry->d_flags &= ~DCACHE_NFSFS_RENAMED;
-	if (data->task.tk_rpcwait == &nfs_delete_queue) {
-		struct rpc_clnt *clnt = data->task.tk_client;
+	if (data->task.tk_rpcwait == &nfs_delete_queue)
 		rpc_wake_up_task(&data->task);
-		nfs_wait_event(clnt, data->waitq, data->completed == 1);
-	}
 	nfs_put_unlinkdata(data);
 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/proc/array.c linux-2.4.29-pre3/fs/proc/array.c
--- linux-2.4.28/fs/proc/array.c	2003-11-28 18:26:21.000000000 +0000
+++ linux-2.4.29-pre3/fs/proc/array.c	2004-12-22 16:07:00.980027568 +0000
@@ -86,10 +86,13 @@ static inline char * task_name(struct ta
 {
 	int i;
 	char * name;
+	char tcomm[sizeof(p->comm)];
+
+	get_task_comm(tcomm, p);
 
 	ADDBUF(buf, "Name:\t");
-	name = p->comm;
-	i = sizeof(p->comm);
+	name = tcomm;
+	i = sizeof(tcomm);
 	do {
 		unsigned char c = *name;
 		name++;
@@ -308,6 +311,7 @@ int proc_pid_stat(struct task_struct *ta
 	int res;
 	pid_t ppid;
 	struct mm_struct *mm;
+	char tcomm[sizeof(task->comm)];
 
 	state = *get_task_state(task);
 	vsize = eip = esp = 0;
@@ -333,6 +337,8 @@ int proc_pid_stat(struct task_struct *ta
 		up_read(&mm->mmap_sem);
 	}
 
+	get_task_comm(tcomm, task);
+
 	wchan = get_wchan(task);
 
 	collect_sigign_sigcatch(task, &sigign, &sigcatch);
@@ -350,7 +356,7 @@ int proc_pid_stat(struct task_struct *ta
 %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu \
 %lu %lu %lu %lu %lu %lu %lu %lu %d %d\n",
 		task->pid,
-		task->comm,
+		tcomm,
 		state,
 		ppid,
 		task->pgrp,
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/proc/base.c linux-2.4.29-pre3/fs/proc/base.c
--- linux-2.4.28/fs/proc/base.c	2004-12-22 16:17:19.287030616 +0000
+++ linux-2.4.29-pre3/fs/proc/base.c	2004-12-22 16:07:03.354666568 +0000
@@ -166,15 +166,16 @@ static int proc_pid_environ(struct task_
 	if (mm)
 		atomic_inc(&mm->mm_users);
 	task_unlock(task);
-	if (mm) {
-		unsigned int len = mm->env_end - mm->env_start;
+	if (mm && mm->env_start && mm->env_start < mm->env_end) {
+		unsigned long len = mm->env_end - mm->env_start;
 		if (len > PAGE_SIZE)
 			len = PAGE_SIZE;
 		res = access_process_vm(task, mm->env_start, buffer, len, 0);
-		if (!may_ptrace_attach(task))
+		if (res >= 0 && !may_ptrace_attach(task))
 			res = -ESRCH;
-		mmput(mm);
 	}
+	if (mm)
+		mmput(mm);
 	return res;
 }
 
@@ -187,31 +188,30 @@ static int proc_pid_cmdline(struct task_
 	if (mm)
 		atomic_inc(&mm->mm_users);
 	task_unlock(task);
-	if (mm) {
-		int len = mm->arg_end - mm->arg_start;
+	if (mm && mm->arg_start && mm->arg_start < mm->arg_end) {
+		unsigned long len = mm->arg_end - mm->arg_start;
 		if (len > PAGE_SIZE)
 			len = PAGE_SIZE;
 		res = access_process_vm(task, mm->arg_start, buffer, len, 0);
-		// If the nul at the end of args has been overwritten, then
-		// assume application is using setproctitle(3).
-		if ( res > 0 && buffer[res-1] != '\0' )
-		{
-			len = strnlen( buffer, res );
-			if ( len < res )
-			{
-			    res = len;
-			}
-			else
-			{
+		/* If the nul at the end of args has been overwritten, then
+		   assume application is using setproctitle(3). */
+		if (res > 0 && buffer[res - 1] != '\0') {
+			len = strnlen(buffer, res);
+			if (len < res) {
+				res = len;
+			} else
+			if (mm->env_start < mm->env_end && res <= PAGE_SIZE) {
 				len = mm->env_end - mm->env_start;
 				if (len > PAGE_SIZE - res)
 					len = PAGE_SIZE - res;
 				res += access_process_vm(task, mm->env_start, buffer+res, len, 0);
-				res = strnlen( buffer, res );
-			}
+				res = strnlen(buffer, res);
+			} else
+				res = 0;
 		}
-		mmput(mm);
 	}
+	if (mm)
+		mmput(mm);
 	return res;
 }
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/proc/generic.c linux-2.4.29-pre3/fs/proc/generic.c
--- linux-2.4.28/fs/proc/generic.c	2004-08-07 23:26:06.000000000 +0000
+++ linux-2.4.29-pre3/fs/proc/generic.c	2004-12-22 16:07:52.531190600 +0000
@@ -490,12 +490,12 @@ struct proc_dir_entry *proc_mknod(const 
 	return ent;
 }
 
-struct proc_dir_entry *proc_mkdir(const char *name, struct proc_dir_entry *parent)
+struct proc_dir_entry *proc_mkdir_mode(const char *name, mode_t mode,
+		struct proc_dir_entry *parent)
 {
 	struct proc_dir_entry *ent;
 
-	ent = proc_create(&parent,name,
-			  (S_IFDIR | S_IRUGO | S_IXUGO),2);
+	ent = proc_create(&parent, name, S_IFDIR | mode, 2);
 	if (ent) {
 		ent->proc_fops = &proc_dir_operations;
 		ent->proc_iops = &proc_dir_inode_operations;
@@ -508,6 +508,12 @@ struct proc_dir_entry *proc_mkdir(const 
 	return ent;
 }
 
+struct proc_dir_entry *proc_mkdir(const char *name,
+		struct proc_dir_entry *parent)
+{
+	return proc_mkdir_mode(name, S_IRUGO | S_IXUGO, parent);
+}
+
 struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
 					 struct proc_dir_entry *parent)
 {
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/proc/proc_tty.c linux-2.4.29-pre3/fs/proc/proc_tty.c
--- linux-2.4.28/fs/proc/proc_tty.c	2000-04-21 22:17:57.000000000 +0000
+++ linux-2.4.29-pre3/fs/proc/proc_tty.c	2004-12-22 16:06:25.637400464 +0000
@@ -15,8 +15,6 @@
 #include <asm/bitops.h>
 
 extern struct tty_driver *tty_drivers;	/* linked list of tty drivers */
-extern struct tty_ldisc ldiscs[];
-
 
 static int tty_drivers_read_proc(char *page, char **start, off_t off,
 				 int count, int *eof, void *data);
@@ -106,12 +104,15 @@ static int tty_ldiscs_read_proc(char *pa
 	int	i;
 	int	len = 0;
 	off_t	begin = 0;
-
+	struct tty_ldisc *ld;
+	
 	for (i=0; i < NR_LDISCS; i++) {
-		if (!(ldiscs[i].flags & LDISC_FLAG_DEFINED))
+		ld = tty_ldisc_get(i);
+		if (ld == NULL)
 			continue;
 		len += sprintf(page+len, "%-10s %2d\n",
-			       ldiscs[i].name ? ldiscs[i].name : "???", i);
+			       ld->name ? ld->name : "???", i);
+		tty_ldisc_put(i);
 		if (len+begin > off+count)
 			break;
 		if (len+begin < off) {
@@ -174,7 +175,13 @@ void __init proc_tty_init(void)
 	if (!proc_mkdir("tty", 0))
 		return;
 	proc_tty_ldisc = proc_mkdir("tty/ldisc", 0);
-	proc_tty_driver = proc_mkdir("tty/driver", 0);
+	/*
+	 * /proc/tty/driver/serial reveals the exact character counts for
+	 * serial links which is just too easy to abuse for inferring
+	 * password lengths and inter-keystroke timings during password
+	 * entry.
+	 */
+	proc_tty_driver = proc_mkdir_mode("tty/driver", S_IRUSR | S_IXUSR, 0);
 
 	create_proc_read_entry("tty/ldiscs", 0, 0, tty_ldiscs_read_proc,NULL);
 	create_proc_read_entry("tty/drivers", 0, 0, tty_drivers_read_proc,NULL);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/Makefile linux-2.4.29-pre3/fs/xfs/Makefile
--- linux-2.4.28/fs/xfs/Makefile	2004-08-07 23:26:06.000000000 +0000
+++ linux-2.4.29-pre3/fs/xfs/Makefile	2004-12-22 16:06:00.210265976 +0000
@@ -57,8 +57,6 @@ obj-m				:= $(O_TARGET)
 
 obj-$(CONFIG_XFS_RT)		+= xfs_rtalloc.o
 obj-$(CONFIG_XFS_POSIX_ACL)	+= xfs_acl.o
-obj-$(CONFIG_XFS_POSIX_CAP)	+= xfs_cap.o
-obj-$(CONFIG_XFS_POSIX_MAC)	+= xfs_mac.o
 
 obj-$(CONFIG_XFS_TRACE)		+= xfs_dir2_trace.o
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/linux-2.4/xfs_aops.c linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_aops.c
--- linux-2.4.28/fs/xfs/linux-2.4/xfs_aops.c	2004-12-22 16:17:19.388015264 +0000
+++ linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_aops.c	2004-12-22 16:07:43.650540664 +0000
@@ -516,13 +516,13 @@ STATIC void
 xfs_submit_page(
 	struct page		*page,
 	struct buffer_head	*bh_arr[],
-	int			cnt)
+	int			bh_count)
 {
 	struct buffer_head	*bh;
 	int			i;
 
-	if (cnt) {
-		for (i = 0; i < cnt; i++) {
+	if (bh_count) {
+		for (i = 0; i < bh_count; i++) {
 			bh = bh_arr[i];
 			set_buffer_async_io(bh);
 			if (buffer_unwritten(bh))
@@ -531,12 +531,13 @@ xfs_submit_page(
 			clear_buffer_dirty(bh);
 		}
 
-		for (i = 0; i < cnt; i++) {
+		for (i = 0; i < bh_count; i++) {
 			refile_buffer(bh_arr[i]);
 			submit_bh(WRITE, bh_arr[i]);
 		}
-	} else
+	} else {
 		unlock_page(page);
+	}
 }
 
 /*
@@ -570,11 +571,13 @@ xfs_convert_page(
 	bh = head = page_buffers(page);
 	do {
 		offset = i << bbits;
+		if (offset >= end)
+			break;
 		if (!(PageUptodate(page) || buffer_uptodate(bh)))
 			continue;
 		if (buffer_mapped(bh) && all_bh &&
 		    !buffer_unwritten(bh) && !buffer_delay(bh)) {
-			if (startio && (offset < end)) {
+			if (startio) {
 				lock_buffer(bh);
 				bh_arr[index++] = bh;
 			}
@@ -602,7 +605,7 @@ xfs_convert_page(
 				ASSERT(private);
 			}
 		}
-		if (startio && (offset < end)) {
+		if (startio) {
 			bh_arr[index++] = bh;
 		} else {
 			unlock_buffer(bh);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/linux-2.4/xfs_buf.c linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_buf.c
--- linux-2.4.28/fs/xfs/linux-2.4/xfs_buf.c	2004-12-22 16:17:19.414011312 +0000
+++ linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_buf.c	2004-12-22 16:05:49.901833096 +0000
@@ -626,7 +626,7 @@ _pagebuf_free_bh(
  *	which may imply that this call will block until those buffers
  *	are unlocked.  No I/O is implied by this call.
  */
-STATIC xfs_buf_t *
+xfs_buf_t *
 _pagebuf_find(				/* find buffer for block	*/
 	xfs_buftarg_t		*target,/* target for block		*/
 	loff_t			ioff,	/* starting offset of range	*/
@@ -719,39 +719,14 @@ found:
 	return (pb);
 }
 
-
-/*
- *	pagebuf_find
- *
- *	pagebuf_find returns a buffer matching the specified range of
- *	data for the specified target, if any of the relevant blocks
- *	are in memory.  The buffer may have unallocated holes, if
- *	some, but not all, of the blocks are in memory.  Even where
- *	pages are present in the buffer, not all of every page may be
- *	valid.
- */
-xfs_buf_t *
-pagebuf_find(				/* find buffer for block	*/
-					/* if the block is in memory	*/
-	xfs_buftarg_t		*target,/* target for block		*/
-	loff_t			ioff,	/* starting offset of range	*/
-	size_t			isize,	/* length of range		*/
-	page_buf_flags_t	flags)	/* PBF_TRYLOCK			*/
-{
-	return _pagebuf_find(target, ioff, isize, flags, NULL);
-}
-
 /*
- *	pagebuf_get
+ *	xfs_buf_get_flags assembles a buffer covering the specified range.
  *
- *	pagebuf_get assembles a buffer covering the specified range.
- *	Some or all of the blocks in the range may be valid.  Storage
- *	in memory for all portions of the buffer will be allocated,
- *	although backing storage may not be.  If PBF_READ is set in
- *	flags, pagebuf_iostart is called also.
+ *	Storage in memory for all portions of the buffer will be allocated,
+ *	although backing storage may not be.
  */
 xfs_buf_t *
-pagebuf_get(				/* allocate a buffer		*/
+xfs_buf_get_flags(			/* allocate a buffer		*/
 	xfs_buftarg_t		*target,/* target for buffer		*/
 	loff_t			ioff,	/* starting offset of range	*/
 	size_t			isize,	/* length of range		*/
@@ -781,8 +756,8 @@ pagebuf_get(				/* allocate a buffer		*/
 	if (!(pb->pb_flags & PBF_MAPPED)) {
 		error = _pagebuf_map_pages(pb, flags);
 		if (unlikely(error)) {
-			printk(KERN_WARNING
-			       "pagebuf_get: failed to map pages\n");
+			printk(KERN_WARNING "%s: failed to map pages\n",
+					__FUNCTION__);
 			goto no_buffer;
 		}
 	}
@@ -796,30 +771,50 @@ pagebuf_get(				/* allocate a buffer		*/
 	pb->pb_bn = ioff;
 	pb->pb_count_desired = pb->pb_buffer_length;
 
-	if (flags & PBF_READ) {
+	PB_TRACE(pb, "get", (unsigned long)flags);
+	return pb;
+
+ no_buffer:
+	if (flags & (PBF_LOCK | PBF_TRYLOCK))
+		pagebuf_unlock(pb);
+	pagebuf_rele(pb);
+	return NULL;
+}
+
+xfs_buf_t *
+xfs_buf_read_flags(
+	xfs_buftarg_t		*target,
+	loff_t			ioff,
+	size_t			isize,
+	page_buf_flags_t	flags)
+{
+	xfs_buf_t		*pb;
+
+	flags |= PBF_READ;
+
+	pb = xfs_buf_get_flags(target, ioff, isize, flags);
+	if (pb) {
 		if (PBF_NOT_DONE(pb)) {
-			PB_TRACE(pb, "get_read", (unsigned long)flags);
+			PB_TRACE(pb, "read", (unsigned long)flags);
 			XFS_STATS_INC(pb_get_read);
 			pagebuf_iostart(pb, flags);
 		} else if (flags & PBF_ASYNC) {
-			PB_TRACE(pb, "get_read_async", (unsigned long)flags);
+			PB_TRACE(pb, "read_async", (unsigned long)flags);
 			/*
 			 * Read ahead call which is already satisfied,
 			 * drop the buffer
 			 */
 			goto no_buffer;
 		} else {
-			PB_TRACE(pb, "get_read_done", (unsigned long)flags);
+			PB_TRACE(pb, "read_done", (unsigned long)flags);
 			/* We do not want read in the flags */
 			pb->pb_flags &= ~PBF_READ;
 		}
-	} else {
-		PB_TRACE(pb, "get_write", (unsigned long)flags);
 	}
 
 	return pb;
 
-no_buffer:
+ no_buffer:
 	if (flags & (PBF_LOCK | PBF_TRYLOCK))
 		pagebuf_unlock(pb);
 	pagebuf_rele(pb);
@@ -857,8 +852,8 @@ pagebuf_readahead(
 	size_t			isize,
 	page_buf_flags_t	flags)
 {
-	flags |= (PBF_TRYLOCK|PBF_READ|PBF_ASYNC|PBF_READ_AHEAD);
-	pagebuf_get(target, ioff, isize, flags);
+	flags |= (PBF_TRYLOCK|PBF_ASYNC|PBF_READ_AHEAD);
+	xfs_buf_read_flags(target, ioff, isize, flags);
 }
 
 xfs_buf_t *
@@ -1434,6 +1429,34 @@ _pagebuf_end_io_partial_pages(
  *	Handling of buftargs.
  */
 
+/*
+ * Wait for any bufs with callbacks that have been submitted but
+ * have not yet returned... walk the hash list for the target.
+ */
+void
+xfs_wait_buftarg(
+	xfs_buftarg_t *target)
+{
+	xfs_buf_t	*pb, *n;
+	pb_hash_t	*h;
+	int		i;
+
+	for (i = 0; i < NHASH; i++) {
+		h = &pbhash[i];
+again:
+		spin_lock(&h->pb_hash_lock);
+		list_for_each_entry_safe(pb, n, &h->pb_hash, pb_hash_list) {
+			if (pb->pb_target == target &&
+					!(pb->pb_flags & PBF_FS_MANAGED)) {
+				spin_unlock(&h->pb_hash_lock);
+				delay(100);
+				goto again;
+			}
+		}
+		spin_unlock(&h->pb_hash_lock);
+	}
+}
+
 void
 xfs_free_buftarg(
 	xfs_buftarg_t		*btp,
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/linux-2.4/xfs_buf.h linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_buf.h
--- linux-2.4.28/fs/xfs/linux-2.4/xfs_buf.h	2004-12-22 16:17:19.418010704 +0000
+++ linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_buf.h	2004-12-22 16:07:30.817491584 +0000
@@ -183,20 +183,36 @@ typedef struct xfs_buf {
 
 /* Finding and Reading Buffers */
 
-extern xfs_buf_t *pagebuf_find(	/* find buffer for block if	*/
+extern xfs_buf_t *_pagebuf_find(	/* find buffer for block if	*/
 					/* the block is in memory	*/
 		xfs_buftarg_t *,	/* inode for block		*/
 		loff_t,			/* starting offset of range	*/
 		size_t,			/* length of range		*/
-		page_buf_flags_t);	/* PBF_LOCK			*/
+		page_buf_flags_t,	/* PBF_LOCK			*/
+	        xfs_buf_t *);		/* newly allocated buffer	*/
 
-extern xfs_buf_t *pagebuf_get(		/* allocate a buffer		*/
+#define xfs_incore(buftarg,blkno,len,lockit) \
+	_pagebuf_find(buftarg, blkno ,len, lockit, NULL)
+
+extern xfs_buf_t *xfs_buf_get_flags(	/* allocate a buffer		*/
 		xfs_buftarg_t *,	/* inode for buffer		*/
 		loff_t,			/* starting offset of range     */
 		size_t,			/* length of range              */
 		page_buf_flags_t);	/* PBF_LOCK, PBF_READ,		*/
 					/* PBF_ASYNC			*/
 
+#define xfs_buf_get(target, blkno, len, flags) \
+	xfs_buf_get_flags((target), (blkno), (len), PBF_LOCK | PBF_MAPPED)
+
+extern xfs_buf_t *xfs_buf_read_flags(	/* allocate and read a buffer	*/
+		xfs_buftarg_t *,	/* inode for buffer		*/
+		loff_t,			/* starting offset of range	*/
+		size_t,			/* length of range		*/
+		page_buf_flags_t);	/* PBF_LOCK, PBF_ASYNC		*/
+
+#define xfs_buf_read(target, blkno, len, flags) \
+	xfs_buf_read_flags((target), (blkno), (len), PBF_LOCK | PBF_MAPPED)
+
 extern xfs_buf_t *pagebuf_lookup(
 		xfs_buftarg_t *,
 		loff_t,			/* starting offset of range	*/
@@ -524,18 +540,6 @@ extern inline xfs_caddr_t xfs_buf_offset
 #define XFS_BUF_SET_VTYPE(bp, type)
 #define XFS_BUF_SET_REF(bp, ref)
 
-#define xfs_buf_read(target, blkno, len, flags) \
-		pagebuf_get((target), (blkno), (len), \
-			PBF_LOCK | PBF_READ | PBF_MAPPED)
-#define xfs_buf_get(target, blkno, len, flags) \
-		pagebuf_get((target), (blkno), (len), \
-			PBF_LOCK | PBF_MAPPED)
-
-#define xfs_buf_read_flags(target, blkno, len, flags) \
-		pagebuf_get((target), (blkno), (len), PBF_READ | (flags))
-#define xfs_buf_get_flags(target, blkno, len, flags) \
-		pagebuf_get((target), (blkno), (len), (flags))
-
 static inline int	xfs_bawrite(void *mp, xfs_buf_t *bp)
 {
 	bp->pb_fspriv3 = mp;
@@ -560,10 +564,6 @@ static inline void	xfs_buf_relse(xfs_buf
 #define xfs_biodone(pb)		    \
 	    pagebuf_iodone(pb, (pb->pb_flags & PBF_FS_DATAIOD), 0)
 
-#define xfs_incore(buftarg,blkno,len,lockit) \
-	    pagebuf_find(buftarg, blkno ,len, lockit)
-
-
 #define xfs_biomove(pb, off, len, data, rw) \
 	    pagebuf_iomove((pb), (off), (len), (data), \
 		((rw) == XFS_B_WRITE) ? PBRW_WRITE : PBRW_READ)
@@ -617,6 +617,7 @@ static inline int xfs_bdwrite(void *mp, 
  
 extern xfs_buftarg_t *xfs_alloc_buftarg(struct block_device *);
 extern void xfs_free_buftarg(xfs_buftarg_t *, int);
+extern void xfs_wait_buftarg(xfs_buftarg_t *);
 extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int);
 extern void xfs_incore_relse(xfs_buftarg_t *, int, int);
 extern int xfs_flush_buftarg(xfs_buftarg_t *, int);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/linux-2.4/xfs_file.c linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_file.c
--- linux-2.4.28/fs/xfs/linux-2.4/xfs_file.c	2004-08-07 23:26:06.000000000 +0000
+++ linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_file.c	2004-12-22 16:06:01.226111544 +0000
@@ -322,7 +322,7 @@ linvfs_file_mmap(
 	vattr_t		va = { .va_mask = XFS_AT_UPDATIME };
 	int		error;
 
-	if ((vp->v_type == VREG) && (vp->v_vfsp->vfs_flag & VFS_DMI)) {
+	if (vp->v_vfsp->vfs_flag & VFS_DMI) {
 		xfs_mount_t	*mp = XFS_VFSTOM(vp->v_vfsp);
 
 		error = -XFS_SEND_MMAP(mp, vma, 0);
@@ -333,6 +333,8 @@ linvfs_file_mmap(
 	vma->vm_ops = &linvfs_file_vm_ops;
 
 	VOP_SETATTR(vp, &va, XFS_AT_UPDATIME, NULL, error);
+	if (!error)
+		vn_revalidate(vp);	/* update Linux inode flags */
 	return 0;
 }
 
@@ -394,7 +396,7 @@ linvfs_mprotect(
 	vnode_t		*vp = LINVFS_GET_VP(vma->vm_file->f_dentry->d_inode);
 	int		error = 0;
 
-	if ((vp->v_type == VREG) && (vp->v_vfsp->vfs_flag & VFS_DMI)) {
+	if (vp->v_vfsp->vfs_flag & VFS_DMI) {
 		if ((vma->vm_flags & VM_MAYSHARE) &&
 		    (newflags & PROT_WRITE) && !(vma->vm_flags & PROT_WRITE)) {
 			xfs_mount_t	*mp = XFS_VFSTOM(vp->v_vfsp);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/linux-2.4/xfs_fs_subr.h linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_fs_subr.h
--- linux-2.4.28/fs/xfs/linux-2.4/xfs_fs_subr.h	2004-08-07 23:26:06.000000000 +0000
+++ linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_fs_subr.h	2004-12-22 16:06:37.699566736 +0000
@@ -40,7 +40,6 @@ struct cred;
 
 extern int	fs_noerr(void);
 extern int	fs_nosys(void);
-extern int	fs_nodev(void);
 extern void	fs_noval(void);
 extern void	fs_tosspages(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
 extern void	fs_flushinval_pages(bhv_desc_t *, xfs_off_t, xfs_off_t, int);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/linux-2.4/xfs_globals.c linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_globals.c
--- linux-2.4.28/fs/xfs/linux-2.4/xfs_globals.c	2004-08-07 23:26:06.000000000 +0000
+++ linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_globals.c	2004-12-22 16:07:38.086386544 +0000
@@ -66,6 +66,8 @@ xfs_param_t xfs_params = {
 	.inherit_noatim = {	0,	1,	1	},
 	.xfs_buf_timer	= {	100/2,	100,	30*100	},
 	.xfs_buf_age	= {	1*100,	15*100,	300*100	},
+	.inherit_nosym	= {	0,	0,	1	},
+	.rotorstep	= {	1,	1,	255	},
 };
 
 /*
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/linux-2.4/xfs_ioctl.c linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_ioctl.c
--- linux-2.4.28/fs/xfs/linux-2.4/xfs_ioctl.c	2004-12-22 16:17:19.430008880 +0000
+++ linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_ioctl.c	2004-12-22 16:07:36.080691456 +0000
@@ -268,7 +268,7 @@ xfs_vget_fsop_handlereq(
 	/*
 	 * Get the XFS inode, building a vnode to go with it.
 	 */
-	error = xfs_iget(mp, NULL, ino, XFS_ILOCK_SHARED, &ip, 0);
+	error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, 0);
 	if (error)
 		return error;
 	if (ip == NULL)
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/linux-2.4/xfs_iops.c linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_iops.c
--- linux-2.4.28/fs/xfs/linux-2.4/xfs_iops.c	2004-08-07 23:26:06.000000000 +0000
+++ linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_iops.c	2004-12-22 16:06:46.607212568 +0000
@@ -173,8 +173,9 @@ linvfs_mknod(
 				 */
 				teardown.d_inode = ip = LINVFS_GET_IP(vp);
 				teardown.d_name = dentry->d_name;
-				remove_inode_hash(ip);
-				make_bad_inode(ip);
+
+				vn_mark_bad(vp);
+
 				if (S_ISDIR(mode))
 					VOP_RMDIR(dvp, &teardown, NULL, err2);
 				else
@@ -302,7 +303,7 @@ linvfs_symlink(
 {
 	struct inode	*ip;
 	vattr_t		va;
-	vnode_t		*dvp;	/* directory containing name to remove */
+	vnode_t		*dvp;	/* directory containing name of symlink */
 	vnode_t		*cvp;	/* used to lookup symlink to put in dentry */
 	int		error;
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/linux-2.4/xfs_linux.h linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_linux.h
--- linux-2.4.28/fs/xfs/linux-2.4/xfs_linux.h	2004-12-22 16:17:19.432008576 +0000
+++ linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_linux.h	2004-12-22 16:07:14.792927688 +0000
@@ -79,6 +79,7 @@
 #include <linux/pagemap.h>
 #include <linux/seq_file.h>
 #include <linux/init.h>
+#include <linux/list.h>
 #include <linux/proc_fs.h>
 
 #include <asm/page.h>
@@ -141,6 +142,8 @@ BUFFER_FNS(Unwritten, unwritten)
 #define xfs_inherit_noatime	xfs_params.inherit_noatim.val
 #define xfs_buf_timer_centisecs	xfs_params.xfs_buf_timer.val
 #define xfs_buf_age_centisecs	xfs_params.xfs_buf_age.val
+#define xfs_inherit_nosymlinks	xfs_params.inherit_nosym.val
+#define xfs_rotorstep		xfs_params.rotorstep.val
 
 #define current_cpu()		smp_processor_id()
 #define current_pid()		(current->pid)
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/linux-2.4/xfs_lrw.c linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_lrw.c
--- linux-2.4.28/fs/xfs/linux-2.4/xfs_lrw.c	2004-12-22 16:17:19.439007512 +0000
+++ linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_lrw.c	2004-12-22 16:05:32.912415880 +0000
@@ -336,11 +336,12 @@ xfs_read(
 		ret = generic_file_read(file, buf, size, offset);
 	}
 
+	if (ret > 0)
+		XFS_STATS_ADD(xs_read_bytes, ret);
+
 	if (!(ioflags & IO_ISLOCKED))
 		xfs_iunlock(ip, XFS_IOLOCK_SHARED);
 
-	XFS_STATS_ADD(xs_read_bytes, ret);
-
 	if (unlikely(ioflags & IO_INVIS)) {
 		/* generic_file_read updates the atime but we need to
 		 * undo that because this I/O was supposed to be invisible.
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/linux-2.4/xfs_super.c linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_super.c
--- linux-2.4.28/fs/xfs/linux-2.4/xfs_super.c	2004-12-22 16:17:19.443006904 +0000
+++ linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_super.c	2004-12-22 16:07:14.751933920 +0000
@@ -129,8 +129,7 @@ xfs_set_inodeops(
 	vnode_t			*vp = LINVFS_GET_VP(inode);
 
 	if (vp->v_type == VNON) {
-		remove_inode_hash(inode);
-		make_bad_inode(inode);
+		vn_mark_bad(vp);
 	} else if (S_ISREG(inode->i_mode)) {
 		inode->i_op = &linvfs_file_inode_operations;
 		inode->i_fop = &linvfs_file_operations;
@@ -211,21 +210,21 @@ xfs_initialize_vnode(
 		bhv_insert(VN_BHV_HEAD(vp), inode_bhv);
 	}
 
-	vp->v_type = IFTOVT(ip->i_d.di_mode);
-
-	/* Have we been called during the new inode create process,
-	 * in which case we are too early to fill in the Linux inode.
+	/*
+	 * We need to set the ops vectors, and unlock the inode, but if
+	 * we have been called during the new inode create process, it is
+	 * too early to fill in the Linux inode.  We will get called a
+	 * second time once the inode is properly set up, and then we can
+	 * finish our work.
 	 */
-	if (vp->v_type == VNON)
-		return;
+	if (ip->i_d.di_mode != 0 && unlock && (inode->i_state & I_NEW)) {
+		vp->v_type = IFTOVT(ip->i_d.di_mode);
+		xfs_revalidate_inode(XFS_BHVTOM(bdp), vp, ip);
+		xfs_set_inodeops(inode);
 
-	xfs_revalidate_inode(XFS_BHVTOM(bdp), vp, ip);
+		ip->i_flags &= ~XFS_INEW;
+		barrier();
 
-	/* For new inodes we need to set the ops vectors,
-	 * and unlock the inode.
-	 */
-	if (unlock && (inode->i_state & I_NEW)) {
-		xfs_set_inodeops(inode);
 		unlock_new_inode(inode);
 	}
 }
@@ -253,25 +252,6 @@ xfs_get_inode(
 	return iget_locked(vfsp->vfs_super, ino);
 }
 
-void
-xfs_flush_inode(
-	xfs_inode_t	*ip)
-{
-	struct inode	*inode = LINVFS_GET_IP(XFS_ITOV(ip));
-
-	filemap_fdatawrite(inode->i_mapping);
-}
-
-void
-xfs_flush_device(
-	xfs_inode_t	*ip)
-{
-	struct inode	*inode = LINVFS_GET_IP(XFS_ITOV(ip));
-
-	fsync_no_super(inode->i_dev);
-	xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC);
-}
-
 struct dentry *
 d_alloc_anon(struct inode *inode)
 {
@@ -427,14 +407,105 @@ linvfs_clear_inode(
 }
 
 
+/*
+ * Enqueue a work item to be picked up by the vfs xfssyncd thread.
+ * Doing this has two advantages:
+ * - It saves on stack space, which is tight in certain situations
+ * - It can be used (with care) as a mechanism to avoid deadlocks.
+ * Flushing while allocating in a full filesystem requires both.
+ */
+STATIC void
+xfs_syncd_queue_work(
+	struct vfs	*vfs,
+	void		*data,
+	void		(*syncer)(vfs_t *, void *))
+{
+	vfs_sync_work_t	*work;
+
+	work = kmem_alloc(sizeof(struct vfs_sync_work), KM_SLEEP);
+	INIT_LIST_HEAD(&work->w_list);
+	work->w_syncer = syncer;
+	work->w_data = data;
+	work->w_vfs = vfs;
+	spin_lock(&vfs->vfs_sync_lock);
+	list_add_tail(&work->w_list, &vfs->vfs_sync_list);
+	spin_unlock(&vfs->vfs_sync_lock);
+	wake_up_process(vfs->vfs_sync_task);
+}
+
+/*
+ * Flush delayed allocate data, attempting to free up reserved space
+ * from existing allocations.  At this point a new allocation attempt
+ * has failed with ENOSPC and we are in the process of scratching our
+ * heads, looking about for more room...
+ */
+STATIC void
+xfs_flush_inode_work(
+	vfs_t		*vfs,
+	void		*inode)
+{
+	filemap_fdatawrite(((struct inode *)inode)->i_mapping);
+	iput((struct inode *)inode);
+}
+
+void
+xfs_flush_inode(
+	xfs_inode_t	*ip)
+{
+	struct inode	*inode = LINVFS_GET_IP(XFS_ITOV(ip));
+	struct vfs	*vfs = XFS_MTOVFS(ip->i_mount);
+
+	igrab(inode);
+	xfs_syncd_queue_work(vfs, inode, xfs_flush_inode_work);
+	delay(HZ/2);
+}
+
+/*
+ * This is the "bigger hammer" version of xfs_flush_inode_work...
+ * (IOW, "If at first you don't succeed, use a Bigger Hammer").
+ */
+STATIC void
+xfs_flush_device_work(
+	vfs_t		*vfs,
+	void		*inode)
+{
+	fsync_no_super(((struct inode *)inode)->i_dev);
+	iput((struct inode *)inode);
+}
+
+void
+xfs_flush_device(
+	xfs_inode_t	*ip)
+{
+	struct inode	*inode = LINVFS_GET_IP(XFS_ITOV(ip));
+	struct vfs	*vfs = XFS_MTOVFS(ip->i_mount);
+
+	igrab(inode);
+	xfs_syncd_queue_work(vfs, inode, xfs_flush_device_work);
+	delay(HZ/2);
+	xfs_log_force(ip->i_mount, (xfs_lsn_t)0, XFS_LOG_FORCE|XFS_LOG_SYNC);
+}
+
 #define SYNCD_FLAGS	(SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR|SYNC_REFCACHE)
+STATIC void
+vfs_sync_worker(
+	vfs_t		*vfsp,
+	void		*unused)
+{
+	int		error;
+
+	if (!(vfsp->vfs_flag & VFS_RDONLY))
+		VFS_SYNC(vfsp, SYNCD_FLAGS, NULL, error);
+}
 
 STATIC int
 xfssyncd(
 	void			*arg)
 {
+	long			timeleft;
 	vfs_t			*vfsp = (vfs_t *) arg;
-	int			error;
+	struct list_head	tmp;
+	struct vfs_sync_work	*work, *n;
 
 	daemonize();
 	reparent_to_init();
@@ -445,18 +516,38 @@ xfssyncd(
 
 	sprintf(current->comm, "xfssyncd");
 
+	vfsp->vfs_sync_work.w_vfs = vfsp;
+	vfsp->vfs_sync_work.w_syncer = vfs_sync_worker;
 	vfsp->vfs_sync_task = current;
 	wmb();
 	wake_up(&vfsp->vfs_wait_sync_task);
 
+	INIT_LIST_HEAD(&tmp);
+	timeleft = (xfs_syncd_centisecs * HZ) / 100;
 	for (;;) {
 		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout((xfs_syncd_centisecs * HZ) / 100);
+		timeleft = schedule_timeout(timeleft);
 		if (vfsp->vfs_flag & VFS_UMOUNT)
 			break;
-		if (vfsp->vfs_flag & VFS_RDONLY)
-			continue;
-		VFS_SYNC(vfsp, SYNCD_FLAGS, NULL, error);
+
+		spin_lock(&vfsp->vfs_sync_lock);
+		if (!timeleft) {
+			timeleft = (xfs_syncd_centisecs * HZ) / 100;
+			INIT_LIST_HEAD(&vfsp->vfs_sync_work.w_list);
+			list_add_tail(&vfsp->vfs_sync_work.w_list,
+					&vfsp->vfs_sync_list);
+		}
+		list_for_each_entry_safe(work, n, &vfsp->vfs_sync_list, w_list)
+			list_move(&work->w_list, &tmp);
+		spin_unlock(&vfsp->vfs_sync_lock);
+
+		list_for_each_entry_safe(work, n, &tmp, w_list) {
+			(*work->w_syncer)(vfsp, work->w_data);
+			list_del(&work->w_list);
+			if (work == &vfsp->vfs_sync_work)
+				continue;
+			kmem_free(work, sizeof(struct vfs_sync_work));
+		}
 	}
 
 	vfsp->vfs_sync_task = NULL;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/linux-2.4/xfs_sysctl.c linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_sysctl.c
--- linux-2.4.28/fs/xfs/linux-2.4/xfs_sysctl.c	2004-08-07 23:26:06.000000000 +0000
+++ linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_sysctl.c	2004-12-22 16:07:37.438485040 +0000
@@ -160,6 +160,16 @@ STATIC ctl_table xfs_table[] = {
 	&sysctl_intvec, NULL,
 	&xfs_params.xfs_buf_age.min, &xfs_params.xfs_buf_age.max},
 
+	{XFS_INHERIT_NOSYM, "inherit_nosymlinks", &xfs_params.inherit_nosym.val,
+	sizeof(int), 0644, NULL, &proc_dointvec_minmax,
+	&sysctl_intvec, NULL,
+	&xfs_params.inherit_nosym.min, &xfs_params.inherit_nosym.max},
+
+	{XFS_ROTORSTEP, "rotorstep", &xfs_params.rotorstep.val,
+	sizeof(int), 0644, NULL, &proc_dointvec_minmax,
+	&sysctl_intvec, NULL, 
+	&xfs_params.rotorstep.min, &xfs_params.rotorstep.max},
+
 	/* please keep this the last entry */
 #ifdef CONFIG_PROC_FS
 	{XFS_STATS_CLEAR, "stats_clear", &xfs_params.stats_clear.val,
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/linux-2.4/xfs_sysctl.h linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_sysctl.h
--- linux-2.4.28/fs/xfs/linux-2.4/xfs_sysctl.h	2004-08-07 23:26:06.000000000 +0000
+++ linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_sysctl.h	2004-12-22 16:06:05.948393648 +0000
@@ -61,6 +61,8 @@ typedef struct xfs_param {
 	xfs_sysctl_val_t inherit_noatim;/* Inherit the "noatime" inode flag. */
 	xfs_sysctl_val_t xfs_buf_timer;	/* Interval between xfsbufd wakeups. */
 	xfs_sysctl_val_t xfs_buf_age;	/* Metadata buffer age before flush. */
+	xfs_sysctl_val_t inherit_nosym;	/* Inherit the "nosymlinks" flag. */
+	xfs_sysctl_val_t rotorstep;	/* inode32 AG rotoring control knob */
 } xfs_param_t;
 
 /*
@@ -97,6 +99,8 @@ enum {
 	XFS_BUF_TIMER = 16,
 	XFS_BUF_AGE = 17,
 	/* XFS_IO_BYPASS = 18, */
+	XFS_INHERIT_NOSYM = 19,
+	XFS_ROTORSTEP = 20,
 };
 
 extern xfs_param_t	xfs_params;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/linux-2.4/xfs_vfs.c linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_vfs.c
--- linux-2.4.28/fs/xfs/linux-2.4/xfs_vfs.c	2004-12-22 16:17:19.453005384 +0000
+++ linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_vfs.c	2004-12-22 16:06:05.134517376 +0000
@@ -262,6 +262,8 @@ vfs_allocate( void )
 
 	vfsp = kmem_zalloc(sizeof(vfs_t), KM_SLEEP);
 	bhv_head_init(VFS_BHVHEAD(vfsp), "vfs");
+	INIT_LIST_HEAD(&vfsp->vfs_sync_list);
+	vfsp->vfs_sync_lock = SPIN_LOCK_UNLOCKED;
 	init_waitqueue_head(&vfsp->vfs_wait_sync_task);
 	init_waitqueue_head(&vfsp->vfs_wait_unfrozen);
 	return vfsp;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/linux-2.4/xfs_vfs.h linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_vfs.h
--- linux-2.4.28/fs/xfs/linux-2.4/xfs_vfs.h	2004-12-22 16:17:19.465003560 +0000
+++ linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_vfs.h	2004-12-22 16:07:12.039346296 +0000
@@ -36,6 +36,7 @@
 #include "xfs_fs.h"
 
 struct fid;
+struct vfs;
 struct cred;
 struct vnode;
 struct statfs;
@@ -45,13 +46,23 @@ struct xfs_mount_args;
 
 typedef struct statfs xfs_statfs_t;
 
+typedef struct vfs_sync_work {
+	struct list_head	w_list;
+	struct vfs		*w_vfs;
+	void			*w_data;	/* syncer routine argument */
+	void			(*w_syncer)(struct vfs *, void *);
+} vfs_sync_work_t;
+
 typedef struct vfs {
 	u_int			vfs_flag;	/* flags */
 	xfs_fsid_t		vfs_fsid;	/* file system ID */
 	xfs_fsid_t		*vfs_altfsid;	/* An ID fixed for life of FS */
 	bhv_head_t		vfs_bh;		/* head of vfs behavior chain */
-	struct super_block	*vfs_super;	/* Linux superblock structure */
-	struct task_struct	*vfs_sync_task;
+	struct super_block	*vfs_super;	/* generic superblock pointer */
+	struct task_struct	*vfs_sync_task;	/* generalised sync thread */
+	vfs_sync_work_t		vfs_sync_work;	/* work item for VFS_SYNC */
+	struct list_head	vfs_sync_list;	/* sync thread work item list */
+	spinlock_t		vfs_sync_lock;	/* work item list lock */
 	wait_queue_head_t	vfs_wait_sync_task;
 	int			vfs_frozen;
 	wait_queue_head_t	vfs_wait_unfrozen;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/linux-2.4/xfs_vnode.c linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_vnode.c
--- linux-2.4.28/fs/xfs/linux-2.4/xfs_vnode.c	2004-08-07 23:26:06.000000000 +0000
+++ linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_vnode.c	2004-12-22 16:07:10.443588888 +0000
@@ -186,8 +186,7 @@ vn_get(
 	 * returning NULL here is OK.
 	 */
 	if (inode->i_state & I_NEW) {
-		remove_inode_hash(inode);
-		make_bad_inode(inode);
+		vn_mark_bad(vp);
 		unlock_new_inode(inode);
 		iput(inode);
 		return NULL;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/linux-2.4/xfs_vnode.h linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_vnode.h
--- linux-2.4.28/fs/xfs/linux-2.4/xfs_vnode.h	2004-08-07 23:26:06.000000000 +0000
+++ linux-2.4.29-pre3/fs/xfs/linux-2.4/xfs_vnode.h	2004-12-22 16:07:33.072148824 +0000
@@ -594,6 +594,23 @@ static __inline__ void vn_flagclr(struct
 		(LINVFS_GET_IP(vp)->i_ctime = (__int32_t)(tvp)->tv_sec)
 
 /*
+ * Dealing with bad inodes
+ */
+static inline void vn_mark_bad(struct vnode *vp)
+{
+	struct inode *inode = LINVFS_GET_IP(vp);
+
+	remove_inode_hash(inode);
+	make_bad_inode(inode);
+}
+
+static inline int VN_BAD(struct vnode *vp)
+{
+	return is_bad_inode(LINVFS_GET_IP(vp));
+}
+
+
+/*
  * Some useful predicates.
  */
 #define	VN_MAPPED(vp)	((LINVFS_GET_IP(vp)->i_mapping->i_mmap != NULL) || \
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/quota/xfs_qm.c linux-2.4.29-pre3/fs/xfs/quota/xfs_qm.c
--- linux-2.4.28/fs/xfs/quota/xfs_qm.c	2004-12-22 16:17:19.516995656 +0000
+++ linux-2.4.29-pre3/fs/xfs/quota/xfs_qm.c	2004-12-22 16:06:20.536175968 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -85,7 +85,6 @@ kmem_shaker_t	xfs_qm_shaker;
 
 STATIC void	xfs_qm_list_init(xfs_dqlist_t *, char *, int);
 STATIC void	xfs_qm_list_destroy(xfs_dqlist_t *);
-STATIC int	xfs_qm_quotacheck(xfs_mount_t *);
 
 STATIC int	xfs_qm_init_quotainos(xfs_mount_t *);
 STATIC int	xfs_qm_shake(int, unsigned int);
@@ -349,7 +348,8 @@ xfs_qm_unmount_quotadestroy(
  */
 int
 xfs_qm_mount_quotas(
-	xfs_mount_t	*mp)
+	xfs_mount_t	*mp,
+	int		mfsi_flags)
 {
 	unsigned long	s;
 	int		error = 0;
@@ -398,22 +398,16 @@ xfs_qm_mount_quotas(
 	/*
 	 * If any of the quotas are not consistent, do a quotacheck.
 	 */
-	if (XFS_QM_NEED_QUOTACHECK(mp)) {
+	if (XFS_QM_NEED_QUOTACHECK(mp) &&
+		!(mfsi_flags & XFS_MFSI_NO_QUOTACHECK)) {
 #ifdef DEBUG
 		cmn_err(CE_NOTE, "Doing a quotacheck. Please wait.");
 #endif
 		if ((error = xfs_qm_quotacheck(mp))) {
-			cmn_err(CE_WARN, "Quotacheck unsuccessful (Error %d): "
-				"Disabling quotas.",
-				error);
-			/*
-			 * We must turn off quotas.
+			/* Quotacheck has failed and quotas have
+			 * been disabled.
 			 */
-			ASSERT(mp->m_quotainfo != NULL);
-			ASSERT(xfs_Gqm != NULL);
-			xfs_qm_destroy_quotainfo(mp);
-			mp->m_qflags = 0;
-			goto write_changes;
+			return XFS_ERROR(error);
 		}
 #ifdef DEBUG
 		cmn_err(CE_NOTE, "Done quotacheck.");
@@ -1788,7 +1782,7 @@ xfs_qm_dqusage_adjust(
 	 * the case in all other instances. It's OK that we do this because
 	 * quotacheck is done only at mount time.
 	 */
-	if ((error = xfs_iget(mp, NULL, ino, XFS_ILOCK_EXCL, &ip, bno))) {
+	if ((error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_EXCL, &ip, bno))) {
 		*res = BULKSTAT_RV_NOTHING;
 		return (error);
 	}
@@ -1875,9 +1869,9 @@ xfs_qm_dqusage_adjust(
 
 /*
  * Walk thru all the filesystem inodes and construct a consistent view
- * of the disk quota world.
+ * of the disk quota world. If the quotacheck fails, disable quotas.
  */
-STATIC int
+int
 xfs_qm_quotacheck(
 	xfs_mount_t	*mp)
 {
@@ -1973,7 +1967,20 @@ xfs_qm_quotacheck(
 	XQM_LIST_PRINT(&(XFS_QI_MPL_LIST(mp)), MPL_NEXT, "++++ Mp list +++");
 
  error_return:
-	cmn_err(CE_NOTE, "XFS quotacheck %s: Done.", mp->m_fsname);
+	if (error) {
+		cmn_err(CE_WARN, "XFS quotacheck %s: Unsuccessful (Error %d): "
+			"Disabling quotas.",
+			mp->m_fsname, error);
+		/*
+		 * We must turn off quotas.
+		 */
+		ASSERT(mp->m_quotainfo != NULL);
+		ASSERT(xfs_Gqm != NULL);
+		xfs_qm_destroy_quotainfo(mp);
+		xfs_mount_reset_sbqflags(mp);
+	} else {
+		cmn_err(CE_NOTE, "XFS quotacheck %s: Done.", mp->m_fsname);
+	}
 	return (error);
 }
 
@@ -2003,14 +2010,14 @@ xfs_qm_init_quotainos(
 		    mp->m_sb.sb_uquotino != NULLFSINO) {
 			ASSERT(mp->m_sb.sb_uquotino > 0);
 			if ((error = xfs_iget(mp, NULL, mp->m_sb.sb_uquotino,
-					     0, &uip, 0)))
+					     0, 0, &uip, 0)))
 				return XFS_ERROR(error);
 		}
 		if (XFS_IS_GQUOTA_ON(mp) &&
 		    mp->m_sb.sb_gquotino != NULLFSINO) {
 			ASSERT(mp->m_sb.sb_gquotino > 0);
 			if ((error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino,
-					     0, &gip, 0))) {
+					     0, 0, &gip, 0))) {
 				if (uip)
 					VN_RELE(XFS_ITOV(uip));
 				return XFS_ERROR(error);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/quota/xfs_qm.h linux-2.4.29-pre3/fs/xfs/quota/xfs_qm.h
--- linux-2.4.28/fs/xfs/quota/xfs_qm.h	2004-12-22 16:17:19.520995048 +0000
+++ linux-2.4.29-pre3/fs/xfs/quota/xfs_qm.h	2004-12-22 16:06:40.606124872 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -182,17 +182,19 @@ typedef struct xfs_dquot_acct {
 #define XFS_QM_HOLD(xqm)	((xqm)->qm_nrefs++)
 #define XFS_QM_RELE(xqm)	((xqm)->qm_nrefs--)
 
+extern void		xfs_mount_reset_sbqflags(xfs_mount_t *);
+
 extern int		xfs_qm_init_quotainfo(xfs_mount_t *);
 extern void		xfs_qm_destroy_quotainfo(xfs_mount_t *);
-extern int		xfs_qm_mount_quotas(xfs_mount_t *);
+extern int		xfs_qm_mount_quotas(xfs_mount_t *, int);
 extern void		xfs_qm_mount_quotainit(xfs_mount_t *, uint);
+extern int		xfs_qm_quotacheck(xfs_mount_t *);
 extern void		xfs_qm_unmount_quotadestroy(xfs_mount_t *);
 extern int		xfs_qm_unmount_quotas(xfs_mount_t *);
 extern int		xfs_qm_write_sb_changes(xfs_mount_t *, __int64_t);
 extern int		xfs_qm_sync(xfs_mount_t *, short);
 
 /* dquot stuff */
-extern void		xfs_qm_dqunlink(xfs_dquot_t *);
 extern boolean_t	xfs_qm_dqalloc_incore(xfs_dquot_t **);
 extern int		xfs_qm_dqattach(xfs_inode_t *, uint);
 extern void		xfs_qm_dqdetach(xfs_inode_t *);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/quota/xfs_qm_bhv.c linux-2.4.29-pre3/fs/xfs/quota/xfs_qm_bhv.c
--- linux-2.4.28/fs/xfs/quota/xfs_qm_bhv.c	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/fs/xfs/quota/xfs_qm_bhv.c	2004-12-22 16:06:21.276063488 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -207,10 +207,9 @@ xfs_qm_syncall(
 }
 
 /*
- * When xfsquotas isn't installed and the superblock had quotas, we need to
- * clear the quotaflags from superblock.
+ * Clear the quotaflags in memory and in the superblock.
  */
-STATIC void
+void
 xfs_mount_reset_sbqflags(
 	xfs_mount_t		*mp)
 {
@@ -241,6 +240,8 @@ xfs_mount_reset_sbqflags(
 	if (xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0,
 				      XFS_DEFAULT_LOG_COUNT)) {
 		xfs_trans_cancel(tp, 0);
+		xfs_fs_cmn_err(CE_ALERT, mp,
+			"xfs_mount_reset_sbqflags: Superblock update failed!");
 		return;
 	}
 	xfs_mod_sb(tp, XFS_SB_QFLAGS);
@@ -294,15 +295,12 @@ xfs_qm_newmount(
 		 */
 		if (quotaondisk && !XFS_QM_NEED_QUOTACHECK(mp)) {
 			/*
-			 * If the xfs quota code isn't installed,
-			 * we have to reset the quotachk'd bit.
 			 * If an error occured, qm_mount_quotas code
 			 * has already disabled quotas. So, just finish
 			 * mounting, and get on with the boring life
 			 * without disk quotas.
 			 */
-			if (xfs_qm_mount_quotas(mp))
-				xfs_mount_reset_sbqflags(mp);
+			xfs_qm_mount_quotas(mp, 0);
 		} else {
 			/*
 			 * Clear the quota flags, but remember them. This
@@ -324,13 +322,13 @@ STATIC int
 xfs_qm_endmount(
 	xfs_mount_t	*mp,
 	uint		needquotamount,
-	uint		quotaflags)
+	uint		quotaflags,
+	int		mfsi_flags)
 {
 	if (needquotamount) {
 		ASSERT(mp->m_qflags == 0);
 		mp->m_qflags = quotaflags;
-		if (xfs_qm_mount_quotas(mp))
-			xfs_mount_reset_sbqflags(mp);
+		xfs_qm_mount_quotas(mp, mfsi_flags);
 	}
 
 #if defined(DEBUG) && defined(XFS_LOUD_RECOVERY)
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/quota/xfs_qm_syscalls.c linux-2.4.29-pre3/fs/xfs/quota/xfs_qm_syscalls.c
--- linux-2.4.28/fs/xfs/quota/xfs_qm_syscalls.c	2004-12-22 16:17:19.552990184 +0000
+++ linux-2.4.29-pre3/fs/xfs/quota/xfs_qm_syscalls.c	2004-12-22 16:06:24.876516136 +0000
@@ -404,7 +404,7 @@ xfs_qm_scall_trunc_qfiles(
 	}
 
 	if ((flags & XFS_DQ_USER) && mp->m_sb.sb_uquotino != NULLFSINO) {
-		error = xfs_iget(mp, NULL, mp->m_sb.sb_uquotino, 0, &qip, 0);
+		error = xfs_iget(mp, NULL, mp->m_sb.sb_uquotino, 0, 0, &qip, 0);
 		if (! error) {
 			(void) xfs_truncate_file(mp, qip);
 			VN_RELE(XFS_ITOV(qip));
@@ -412,7 +412,7 @@ xfs_qm_scall_trunc_qfiles(
 	}
 
 	if ((flags & XFS_DQ_GROUP) && mp->m_sb.sb_gquotino != NULLFSINO) {
-		error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 0, &qip, 0);
+		error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 0, 0, &qip, 0);
 		if (! error) {
 			(void) xfs_truncate_file(mp, qip);
 			VN_RELE(XFS_ITOV(qip));
@@ -555,11 +555,13 @@ xfs_qm_scall_getqstat(
 		gip = mp->m_quotainfo->qi_gquotaip;
 	}
 	if (!uip && mp->m_sb.sb_uquotino != NULLFSINO) {
-		if (xfs_iget(mp, NULL, mp->m_sb.sb_uquotino, 0, &uip, 0) == 0)
+		if (xfs_iget(mp, NULL, mp->m_sb.sb_uquotino,
+					0, 0, &uip, 0) == 0)
 			tempuqip = B_TRUE;
 	}
 	if (!gip && mp->m_sb.sb_gquotino != NULLFSINO) {
-		if (xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, 0, &gip, 0) == 0)
+		if (xfs_iget(mp, NULL, mp->m_sb.sb_gquotino,
+					0, 0, &gip, 0) == 0)
 			tempgqip = B_TRUE;
 	}
 	if (uip) {
@@ -1338,7 +1340,7 @@ xfs_qm_internalqcheck_adjust(
 	ipreleased = B_FALSE;
  again:
 	lock_flags = XFS_ILOCK_SHARED;
-	if ((error = xfs_iget(mp, NULL, ino, lock_flags, &ip, bno))) {
+	if ((error = xfs_iget(mp, NULL, ino, 0, lock_flags, &ip, bno))) {
 		*res = BULKSTAT_RV_NOTHING;
 		return (error);
 	}
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/xfs_acl.h linux-2.4.29-pre3/fs/xfs/xfs_acl.h
--- linux-2.4.28/fs/xfs/xfs_acl.h	2004-12-22 16:17:19.609981520 +0000
+++ linux-2.4.29-pre3/fs/xfs/xfs_acl.h	2004-12-22 16:05:31.134686136 +0000
@@ -74,8 +74,6 @@ extern struct kmem_zone *xfs_acl_zone;
 
 extern int xfs_acl_inherit(struct vnode *, struct vattr *, xfs_acl_t *);
 extern int xfs_acl_iaccess(struct xfs_inode *, mode_t, cred_t *);
-extern int xfs_acl_get(struct vnode *, xfs_acl_t *, xfs_acl_t *);
-extern int xfs_acl_set(struct vnode *, xfs_acl_t *, xfs_acl_t *);
 extern int xfs_acl_vtoacl(struct vnode *, xfs_acl_t *, xfs_acl_t *);
 extern int xfs_acl_vhasacl_access(struct vnode *);
 extern int xfs_acl_vhasacl_default(struct vnode *);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/xfs_alloc.c linux-2.4.29-pre3/fs/xfs/xfs_alloc.c
--- linux-2.4.28/fs/xfs/xfs_alloc.c	2004-12-22 16:17:19.624979240 +0000
+++ linux-2.4.29-pre3/fs/xfs/xfs_alloc.c	2004-12-22 16:05:40.251300200 +0000
@@ -2247,6 +2247,7 @@ xfs_alloc_vextent(
 	xfs_alloctype_t	type;	/* input allocation type */
 	int		bump_rotor = 0;
 	int		no_min = 0;
+	xfs_agnumber_t	rotorstep = xfs_rotorstep; /* inode32 agf stepper */
 
 	mp = args->mp;
 	type = args->otype = args->type;
@@ -2310,7 +2311,9 @@ xfs_alloc_vextent(
 		 */
 		if ((args->userdata  == XFS_ALLOC_INITIAL_USER_DATA) &&
 		    (mp->m_flags & XFS_MOUNT_32BITINODES)) {
-			args->fsbno = XFS_AGB_TO_FSB(mp, mp->m_agfrotor, 0);
+			args->fsbno = XFS_AGB_TO_FSB(mp,
+					((mp->m_agfrotor / rotorstep) %
+					mp->m_sb.sb_agcount), 0);
 			bump_rotor = 1;
 		}
 		args->agbno = XFS_FSB_TO_AGBNO(mp, args->fsbno);
@@ -2326,7 +2329,8 @@ xfs_alloc_vextent(
 			/*
 			 * Start with the last place we left off.
 			 */
-			args->agno = sagno = mp->m_agfrotor;
+			args->agno = sagno = (mp->m_agfrotor / rotorstep) %
+					mp->m_sb.sb_agcount;
 			args->type = XFS_ALLOCTYPE_THIS_AG;
 			flags = XFS_ALLOC_FLAG_TRYLOCK;
 		} else if (type == XFS_ALLOCTYPE_FIRST_AG) {
@@ -2400,8 +2404,14 @@ xfs_alloc_vextent(
 			}
 		}
 		up_read(&mp->m_peraglock);
-		if (bump_rotor || (type == XFS_ALLOCTYPE_ANY_AG))
-			mp->m_agfrotor = (args->agno + 1) % mp->m_sb.sb_agcount;
+		if (bump_rotor || (type == XFS_ALLOCTYPE_ANY_AG)) {
+			if (args->agno == sagno)
+				mp->m_agfrotor = (mp->m_agfrotor + 1) %
+					(mp->m_sb.sb_agcount * rotorstep);
+			else
+				mp->m_agfrotor = (args->agno * rotorstep + 1) %
+					(mp->m_sb.sb_agcount * rotorstep);
+		}
 		break;
 	default:
 		ASSERT(0);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/xfs_attr.c linux-2.4.29-pre3/fs/xfs/xfs_attr.c
--- linux-2.4.28/fs/xfs/xfs_attr.c	2004-12-22 16:17:19.687969664 +0000
+++ linux-2.4.29-pre3/fs/xfs/xfs_attr.c	2004-12-22 16:07:00.649077880 +0000
@@ -121,22 +121,14 @@ xfs_attr_fetch(xfs_inode_t *ip, char *na
 	xfs_da_args_t   args;
 	int             error;
 
-	if (XFS_FORCED_SHUTDOWN(ip->i_mount))
-		return(EIO);
-
 	if ((XFS_IFORK_Q(ip) == 0) ||
 	    (ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
 	     ip->i_d.di_anextents == 0))
 		return(ENOATTR);
 
-	if (!(flags & ATTR_KERNACCESS)) {
-		xfs_ilock(ip, XFS_ILOCK_SHARED);
-
-		if (!(flags & ATTR_SECURE) &&
-		    ((error = xfs_iaccess(ip, S_IRUSR, cred)))) {
-			xfs_iunlock(ip, XFS_ILOCK_SHARED);
+	if (!(flags & (ATTR_KERNACCESS|ATTR_SECURE))) {
+		if ((error = xfs_iaccess(ip, S_IRUSR, cred)))
 			return(XFS_ERROR(error));
-		}
 	}
 
 	/*
@@ -167,9 +159,6 @@ xfs_attr_fetch(xfs_inode_t *ip, char *na
 		error = xfs_attr_node_get(&args);
 	}
 
-	if (!(flags & ATTR_KERNACCESS))
-		xfs_iunlock(ip, XFS_ILOCK_SHARED);
-
 	/*
 	 * Return the number of bytes in the value to the caller.
 	 */
@@ -185,7 +174,7 @@ xfs_attr_get(bhv_desc_t *bdp, char *name
 	     int flags, struct cred *cred)
 {
 	xfs_inode_t	*ip = XFS_BHVTOI(bdp);
-	int		namelen;
+	int		error, namelen;
 
 	XFS_STATS_INC(xs_attr_get);
 
@@ -195,7 +184,13 @@ xfs_attr_get(bhv_desc_t *bdp, char *name
 	if (namelen >= MAXNAMELEN)
 		return(EFAULT);		/* match IRIX behaviour */
 
-	return xfs_attr_fetch(ip, name, namelen, value, valuelenp, flags, cred);
+	if (XFS_FORCED_SHUTDOWN(ip->i_mount))
+		return(EIO);
+
+	xfs_ilock(ip, XFS_ILOCK_SHARED);
+	error = xfs_attr_fetch(ip, name, namelen, value, valuelenp, flags, cred);
+	xfs_iunlock(ip, XFS_ILOCK_SHARED);
+	return(error);
 }
 
 /*ARGSUSED*/
@@ -718,16 +713,15 @@ xfs_attr_inactive(xfs_inode_t *dp)
 	mp = dp->i_mount;
 	ASSERT(! XFS_NOT_DQATTACHED(mp, dp));
 
-	/* XXXsup - why on earth are we taking ILOCK_EXCL here??? */
-	xfs_ilock(dp, XFS_ILOCK_EXCL);
+	xfs_ilock(dp, XFS_ILOCK_SHARED);
 	if ((XFS_IFORK_Q(dp) == 0) ||
 	    (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) ||
 	    (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
 	     dp->i_d.di_anextents == 0)) {
-		xfs_iunlock(dp, XFS_ILOCK_EXCL);
+		xfs_iunlock(dp, XFS_ILOCK_SHARED);
 		return(0);
 	}
-	xfs_iunlock(dp, XFS_ILOCK_EXCL);
+	xfs_iunlock(dp, XFS_ILOCK_SHARED);
 
 	/*
 	 * Start our first transaction of the day.
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/xfs_attr_leaf.h linux-2.4.29-pre3/fs/xfs/xfs_attr_leaf.h
--- linux-2.4.28/fs/xfs/xfs_attr_leaf.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/fs/xfs/xfs_attr_leaf.h	2004-12-22 16:07:38.317351432 +0000
@@ -246,7 +246,6 @@ int	xfs_attr_shortform_getvalue(struct x
 int	xfs_attr_shortform_to_leaf(struct xfs_da_args *args);
 int	xfs_attr_shortform_remove(struct xfs_da_args *remove);
 int	xfs_attr_shortform_list(struct xfs_attr_list_context *context);
-int	xfs_attr_shortform_replace(struct xfs_da_args *args);
 int	xfs_attr_shortform_allfit(struct xfs_dabuf *bp, struct xfs_inode *dp);
 
 /*
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/xfs_bmap_btree.h linux-2.4.29-pre3/fs/xfs/xfs_bmap_btree.h
--- linux-2.4.28/fs/xfs/xfs_bmap_btree.h	2004-12-22 16:17:19.777955984 +0000
+++ linux-2.4.29-pre3/fs/xfs/xfs_bmap_btree.h	2004-12-22 16:07:07.683008560 +0000
@@ -551,13 +551,6 @@ xfs_bmbt_insert(
 	struct xfs_btree_cur *,
 	int *);
 
-int
-xfs_bmbt_insert_many(
-	struct xfs_btree_cur *,
-	int,
-	xfs_bmbt_rec_t *,
-	int *);
-
 void
 xfs_bmbt_log_block(
 	struct xfs_btree_cur *,
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/xfs_cap.c linux-2.4.29-pre3/fs/xfs/xfs_cap.c
--- linux-2.4.28/fs/xfs/xfs_cap.c	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/fs/xfs/xfs_cap.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,206 +0,0 @@
-/*
- * Copyright (c) 2002 Silicon Graphics, Inc.  All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like.  Any license provided herein, whether implied or
- * otherwise, applies only to this software file.  Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA  94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-
-#include "xfs.h"
-
-STATIC int xfs_cap_allow_set(vnode_t *);
-
-
-/*
- * Test for existence of capability attribute as efficiently as possible.
- */
-int
-xfs_cap_vhascap(
-	vnode_t		*vp)
-{
-	int		error;
-	int		len = sizeof(xfs_cap_set_t);
-	int		flags = ATTR_KERNOVAL|ATTR_ROOT;
-
-	VOP_ATTR_GET(vp, SGI_CAP_LINUX, NULL, &len, flags, sys_cred, error);
-	return (error == 0);
-}
-
-/*
- * Convert from extended attribute representation to in-memory for XFS.
- */
-STATIC int
-posix_cap_xattr_to_xfs(
-	posix_cap_xattr		*src,
-	size_t			size,
-	xfs_cap_set_t		*dest)
-{
-	if (!src || !dest)
-		return EINVAL;
-
-	if (src->c_version != cpu_to_le32(POSIX_CAP_XATTR_VERSION))
-		return EINVAL;
-	if (src->c_abiversion != cpu_to_le32(_LINUX_CAPABILITY_VERSION))
-		return EINVAL;
-
-	if (size < sizeof(posix_cap_xattr))
-		return EINVAL;
-
-	ASSERT(sizeof(dest->cap_effective) == sizeof(src->c_effective));
-
-	dest->cap_effective	= src->c_effective;
-	dest->cap_permitted	= src->c_permitted;
-	dest->cap_inheritable	= src->c_inheritable;
-
-	return 0;
-}
-
-/*
- * Convert from in-memory XFS to extended attribute representation.
- */
-STATIC int
-posix_cap_xfs_to_xattr(
-	xfs_cap_set_t		*src,
-	posix_cap_xattr		*xattr_cap,
-	size_t			size)
-{
-	size_t			new_size = posix_cap_xattr_size();
-
-	if (size < new_size)
-		return -ERANGE;
-
-	ASSERT(sizeof(xattr_cap->c_effective) == sizeof(src->cap_effective));
-
-	xattr_cap->c_version	= cpu_to_le32(POSIX_CAP_XATTR_VERSION);
-	xattr_cap->c_abiversion	= cpu_to_le32(_LINUX_CAPABILITY_VERSION);
-	xattr_cap->c_effective	= src->cap_effective;
-	xattr_cap->c_permitted	= src->cap_permitted;
-	xattr_cap->c_inheritable= src->cap_inheritable;
-
-	return new_size;
-}
-
-int
-xfs_cap_vget(
-	vnode_t		*vp,
-	void		*cap,
-	size_t		size)
-{
-	int		error;
-	int		len = sizeof(xfs_cap_set_t);
-	int		flags = ATTR_ROOT;
-	xfs_cap_set_t	xfs_cap = { 0 };
-	posix_cap_xattr	*xattr_cap = cap;
-	char		*data = (char *)&xfs_cap;
-
-	VN_HOLD(vp);
-	if ((error = _MAC_VACCESS(vp, NULL, VREAD)))
-		goto out;
-
-	if (!size) {
-		flags |= ATTR_KERNOVAL;
-		data = NULL;
-	}
-	VOP_ATTR_GET(vp, SGI_CAP_LINUX, data, &len, flags, sys_cred, error);
-	if (error)
-		goto out;
-	ASSERT(len == sizeof(xfs_cap_set_t));
-
-	error = (size)? -posix_cap_xattr_size() :
-			-posix_cap_xfs_to_xattr(&xfs_cap, xattr_cap, size);
-out:
-	VN_RELE(vp);
-	return -error;
-}
-
-int
-xfs_cap_vremove(
-	vnode_t		*vp)
-{
-	int		error;
-
-	VN_HOLD(vp);
-	error = xfs_cap_allow_set(vp);
-	if (!error) {
-		VOP_ATTR_REMOVE(vp, SGI_CAP_LINUX, ATTR_ROOT, sys_cred, error);
-		if (error == ENOATTR)
-			error = 0;	/* 'scool */
-	}
-	VN_RELE(vp);
-	return -error;
-}
-
-int
-xfs_cap_vset(
-	vnode_t			*vp,
-	void			*cap,
-	size_t			size)
-{
-	posix_cap_xattr		*xattr_cap = cap;
-	xfs_cap_set_t		xfs_cap;
-	int			error;
-
-	if (!cap)
-		return -EINVAL;
-
-	error = posix_cap_xattr_to_xfs(xattr_cap, size, &xfs_cap);
-	if (error)
-		return -error;
-
-	VN_HOLD(vp);
-	error = xfs_cap_allow_set(vp);
-	if (error)
-		goto out;
-
-	VOP_ATTR_SET(vp, SGI_CAP_LINUX, (char *)&xfs_cap,
-			sizeof(xfs_cap_set_t), ATTR_ROOT, sys_cred, error);
-out:
-	VN_RELE(vp);
-	return -error;
-}
-
-STATIC int
-xfs_cap_allow_set(
-	vnode_t		*vp)
-{
-	vattr_t		va;
-	int		error;
-
-	if (vp->v_vfsp->vfs_flag & VFS_RDONLY)
-		return EROFS;
-	if (vp->v_inode.i_flags & (S_IMMUTABLE|S_APPEND))
-		return EPERM;
-	if ((error = _MAC_VACCESS(vp, NULL, VWRITE)))
-		return error;
-	va.va_mask = XFS_AT_UID;
-	VOP_GETATTR(vp, &va, 0, NULL, error);
-	if (error)
-		return error;
-	if (va.va_uid != current->fsuid && !capable(CAP_FOWNER))
-		return EPERM;
-	return error;
-}
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/xfs_dinode.h linux-2.4.29-pre3/fs/xfs/xfs_dinode.h
--- linux-2.4.28/fs/xfs/xfs_dinode.h	2004-12-22 16:17:19.823948992 +0000
+++ linux-2.4.29-pre3/fs/xfs/xfs_dinode.h	2004-12-22 16:06:59.760213008 +0000
@@ -457,6 +457,8 @@ xfs_dinode_t *xfs_buf_to_dinode(struct x
 #define XFS_DIFLAG_NOATIME_BIT   6	/* do not update atime */
 #define XFS_DIFLAG_NODUMP_BIT    7	/* do not dump */
 #define XFS_DIFLAG_RTINHERIT_BIT 8	/* create with realtime bit set */
+#define XFS_DIFLAG_PROJINHERIT_BIT  9	/* create with parents projid */
+#define XFS_DIFLAG_NOSYMLINKS_BIT  10	/* disallow symlink creation */
 #define XFS_DIFLAG_REALTIME      (1 << XFS_DIFLAG_REALTIME_BIT)
 #define XFS_DIFLAG_PREALLOC      (1 << XFS_DIFLAG_PREALLOC_BIT)
 #define XFS_DIFLAG_NEWRTBM       (1 << XFS_DIFLAG_NEWRTBM_BIT)
@@ -466,10 +468,13 @@ xfs_dinode_t *xfs_buf_to_dinode(struct x
 #define XFS_DIFLAG_NOATIME       (1 << XFS_DIFLAG_NOATIME_BIT)
 #define XFS_DIFLAG_NODUMP        (1 << XFS_DIFLAG_NODUMP_BIT)
 #define XFS_DIFLAG_RTINHERIT     (1 << XFS_DIFLAG_RTINHERIT_BIT)
+#define XFS_DIFLAG_PROJINHERIT   (1 << XFS_DIFLAG_PROJINHERIT_BIT)
+#define XFS_DIFLAG_NOSYMLINKS    (1 << XFS_DIFLAG_NOSYMLINKS_BIT)
 
 #define XFS_DIFLAG_ANY \
 	(XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \
 	 XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \
-	 XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP | XFS_DIFLAG_RTINHERIT)
+	 XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP | XFS_DIFLAG_RTINHERIT | \
+	 XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS)
 
 #endif	/* __XFS_DINODE_H__ */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/xfs_fs.h linux-2.4.29-pre3/fs/xfs/xfs_fs.h
--- linux-2.4.28/fs/xfs/xfs_fs.h	2004-12-22 16:17:19.828948232 +0000
+++ linux-2.4.29-pre3/fs/xfs/xfs_fs.h	2004-12-22 16:06:36.302779080 +0000
@@ -77,6 +77,8 @@ struct fsxattr {
 #define XFS_XFLAG_NOATIME	0x00000040	/* do not update access time */
 #define XFS_XFLAG_NODUMP	0x00000080	/* do not include in backups */
 #define XFS_XFLAG_RTINHERIT	0x00000100	/* create with rt bit set */
+#define XFS_XFLAG_PROJINHERIT	0x00000200	/* create with parents projid */
+#define XFS_XFLAG_NOSYMLINKS	0x00000400	/* disallow symlink creation */
 #define XFS_XFLAG_HASATTR	0x80000000	/* no DIFLAG for this	*/
 
 /*
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/xfs_iget.c linux-2.4.29-pre3/fs/xfs/xfs_iget.c
--- linux-2.4.28/fs/xfs/xfs_iget.c	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/fs/xfs/xfs_iget.c	2004-12-22 16:06:05.718428608 +0000
@@ -169,6 +169,7 @@ xfs_iget_core(
 	xfs_mount_t	*mp,
 	xfs_trans_t	*tp,
 	xfs_ino_t	ino,
+	uint		flags,
 	uint		lock_flags,
 	xfs_inode_t	**ipp,
 	xfs_daddr_t	bno)
@@ -180,7 +181,6 @@ xfs_iget_core(
 	ulong		version;
 	int		error;
 	/* REFERENCED */
-	int		newnode;
 	xfs_chash_t	*ch;
 	xfs_chashlist_t	*chl, *chlnew;
 	SPLDECL(s);
@@ -193,11 +193,22 @@ again:
 
 	for (ip = ih->ih_next; ip != NULL; ip = ip->i_next) {
 		if (ip->i_ino == ino) {
+			/*
+			 * If INEW is set this inode is being set up
+			 * we need to pause and try again.
+			 */
+			if (ip->i_flags & XFS_INEW) {
+				read_unlock(&ih->ih_lock);
+				delay(1);
+				XFS_STATS_INC(xs_ig_frecycle);
 
-			inode_vp = XFS_ITOV_NULL(ip);
+				goto again;
+			}
 
+			inode_vp = XFS_ITOV_NULL(ip);
 			if (inode_vp == NULL) {
-				/* If IRECLAIM is set this inode is
+				/*
+				 * If IRECLAIM is set this inode is
 				 * on its way out of the system,
 				 * we need to pause and try again.
 				 */
@@ -250,14 +261,15 @@ again:
 			XFS_STATS_INC(xs_ig_found);
 
 finish_inode:
-			if (lock_flags != 0) {
-				xfs_ilock(ip, lock_flags);
-			}
-
-			newnode = (ip->i_d.di_mode == 0);
-			if (newnode) {
+			if (ip->i_d.di_mode == 0) {
+				if (!(flags & IGET_CREATE))
+					return ENOENT;
 				xfs_iocore_inode_reinit(ip);
 			}
+	
+			if (lock_flags != 0)
+				xfs_ilock(ip, lock_flags);
+
 			ip->i_flags &= ~XFS_ISTALE;
 
 			vn_trace_exit(vp, "xfs_iget.found",
@@ -293,6 +305,11 @@ finish_inode:
 	if (lock_flags != 0) {
 		xfs_ilock(ip, lock_flags);
 	}
+		
+	if ((ip->i_d.di_mode == 0) && !(flags & IGET_CREATE)) {
+		xfs_idestroy(ip);
+		return ENOENT;
+	}
 
 	/*
 	 * Put ip on its hash chain, unless someone else hashed a duplicate
@@ -324,6 +341,7 @@ finish_inode:
 	ih->ih_next = ip;
 	ip->i_udquot = ip->i_gdquot = NULL;
 	ih->ih_version++;
+	ip->i_flags |= XFS_INEW;
 
 	write_unlock(&ih->ih_lock);
 
@@ -404,8 +422,6 @@ finish_inode:
 
 	XFS_MOUNT_IUNLOCK(mp);
 
-	newnode = 1;
-
  return_ip:
 	ASSERT(ip->i_df.if_ext_max ==
 	       XFS_IFORK_DSIZE(ip) / sizeof(xfs_bmbt_rec_t));
@@ -434,6 +450,7 @@ xfs_iget(
 	xfs_mount_t	*mp,
 	xfs_trans_t	*tp,
 	xfs_ino_t	ino,
+	uint		flags,
 	uint		lock_flags,
 	xfs_inode_t	**ipp,
 	xfs_daddr_t	bno)
@@ -454,11 +471,10 @@ retry:
 		if (inode->i_state & I_NEW) {
 inode_allocate:
 			vn_initialize(inode);
-			error = xfs_iget_core(vp, mp, tp, ino,
-						lock_flags, ipp, bno);
+			error = xfs_iget_core(vp, mp, tp, ino, flags,
+					lock_flags, ipp, bno);
 			if (error) {
-				remove_inode_hash(inode);
-				make_bad_inode(inode);
+				vn_mark_bad(vp);
 				if (inode->i_state & I_NEW)
 					unlock_new_inode(inode);
 				iput(inode);
@@ -582,12 +598,12 @@ xfs_iput_new(xfs_inode_t	*ip,
 
 	vn_trace_entry(vp, "xfs_iput_new", (inst_t *)__return_address);
 
-	/* We shouldn't get here without this being true, but just in case */
-	if (inode->i_state & I_NEW) {
-		remove_inode_hash(inode);
-		make_bad_inode(inode);
-		unlock_new_inode(inode);
+	if ((ip->i_d.di_mode == 0)) {
+		ASSERT(!(ip->i_flags & XFS_IRECLAIMABLE));
+		vn_mark_bad(vp);
 	}
+	if (inode->i_state & I_NEW)
+		unlock_new_inode(inode);
 	if (lock_flags)
 		xfs_iunlock(ip, lock_flags);
 	VN_RELE(vp);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/xfs_inode.c linux-2.4.29-pre3/fs/xfs/xfs_inode.c
--- linux-2.4.28/fs/xfs/xfs_inode.c	2004-12-22 16:17:19.873941392 +0000
+++ linux-2.4.29-pre3/fs/xfs/xfs_inode.c	2004-12-22 16:07:44.623392768 +0000
@@ -881,6 +881,10 @@ xfs_dic2xflags(
 			flags |= XFS_XFLAG_NODUMP;
 		if (di_flags & XFS_DIFLAG_RTINHERIT)
 			flags |= XFS_XFLAG_RTINHERIT;
+		if (di_flags & XFS_DIFLAG_PROJINHERIT)
+			flags |= XFS_XFLAG_PROJINHERIT;
+		if (di_flags & XFS_DIFLAG_NOSYMLINKS)
+			flags |= XFS_XFLAG_NOSYMLINKS;
 	}
 	return flags;
 }
@@ -1159,7 +1163,8 @@ xfs_ialloc(
 	 * This is because we're setting fields here we need
 	 * to prevent others from looking at until we're done.
 	 */
-	error = xfs_trans_iget(tp->t_mountp, tp, ino, XFS_ILOCK_EXCL, &ip);
+	error = xfs_trans_iget(tp->t_mountp, tp, ino,
+			IGET_CREATE, XFS_ILOCK_EXCL, &ip);
 	if (error != 0) {
 		return error;
 	}
@@ -1257,6 +1262,9 @@ xfs_ialloc(
 			if ((pip->i_d.di_flags & XFS_DIFLAG_SYNC) &&
 			    xfs_inherit_sync)
 				ip->i_d.di_flags |= XFS_DIFLAG_SYNC;
+			if ((pip->i_d.di_flags & XFS_DIFLAG_NOSYMLINKS) &&
+			    xfs_inherit_nosymlinks)
+				ip->i_d.di_flags |= XFS_DIFLAG_NOSYMLINKS;
 		}
 		/* FALLTHROUGH */
 	case S_IFLNK:
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/xfs_inode.h linux-2.4.29-pre3/fs/xfs/xfs_inode.h
--- linux-2.4.28/fs/xfs/xfs_inode.h	2004-08-07 23:26:06.000000000 +0000
+++ linux-2.4.29-pre3/fs/xfs/xfs_inode.h	2004-12-22 16:06:42.071902040 +0000
@@ -381,6 +381,7 @@ void xfs_ifork_next_set(xfs_inode_t *ip,
 #define XFS_IRECLAIM    0x0008  /* we have started reclaiming this inode    */
 #define XFS_ISTALE	0x0010	/* inode has been staled */
 #define XFS_IRECLAIMABLE 0x0020 /* inode can be reclaimed */
+#define XFS_INEW	0x0040
 
 /*
  * Flags for inode locking.
@@ -465,6 +466,9 @@ xfs_inode_t *xfs_bhvtoi(struct bhv_desc 
 /*
  * xfs_iget.c prototypes.
  */
+
+#define IGET_CREATE	1
+
 void		xfs_ihash_init(struct xfs_mount *);
 void		xfs_ihash_free(struct xfs_mount *);
 void		xfs_chash_init(struct xfs_mount *);
@@ -473,7 +477,7 @@ xfs_inode_t	*xfs_inode_incore(struct xfs
 				  struct xfs_trans *);
 void            xfs_inode_lock_init(xfs_inode_t *, struct vnode *);
 int		xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
-			 uint, xfs_inode_t **, xfs_daddr_t);
+			 uint, uint, xfs_inode_t **, xfs_daddr_t);
 void		xfs_iput(xfs_inode_t *, uint);
 void		xfs_iput_new(xfs_inode_t *, uint);
 void		xfs_ilock(xfs_inode_t *, uint);
@@ -508,7 +512,6 @@ void		xfs_xlate_dinode_core(xfs_caddr_t,
 uint		xfs_dic2xflags(struct xfs_dinode_core *, xfs_arch_t);
 int		xfs_ifree(struct xfs_trans *, xfs_inode_t *,
 			   struct xfs_bmap_free *);
-int		xfs_atruncate_start(xfs_inode_t *);
 void		xfs_itruncate_start(xfs_inode_t *, uint, xfs_fsize_t);
 int		xfs_itruncate_finish(struct xfs_trans **, xfs_inode_t *,
 				     xfs_fsize_t, int, int);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/xfs_itable.c linux-2.4.29-pre3/fs/xfs/xfs_itable.c
--- linux-2.4.28/fs/xfs/xfs_itable.c	2004-12-22 16:17:19.889938960 +0000
+++ linux-2.4.29-pre3/fs/xfs/xfs_itable.c	2004-12-22 16:07:37.119533528 +0000
@@ -102,7 +102,7 @@ xfs_bulkstat_one(
 		/* We're not being passed a pointer to a dinode.  This happens
 		 * if BULKSTAT_FG_IGET is selected.  Do the iget.
 		 */
-		error = xfs_iget(mp, NULL, ino, XFS_ILOCK_SHARED, &ip, bno);
+		error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, bno);
 		if (error) {
 			*stat = BULKSTAT_RV_NOTHING;
 			return error;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/xfs_log.c linux-2.4.29-pre3/fs/xfs/xfs_log.c
--- linux-2.4.28/fs/xfs/xfs_log.c	2004-12-22 16:17:19.911935616 +0000
+++ linux-2.4.29-pre3/fs/xfs/xfs_log.c	2004-12-22 16:07:17.596501480 +0000
@@ -902,20 +902,15 @@ xlog_space_left(xlog_t *log, int cycle, 
 	} else {
 		/*
 		 * The reservation head is behind the tail.
-		 * This can only happen when the AIL is empty so the tail
-		 * is equal to the head and the l_roundoff value in the
-		 * log structure is taking up the difference between the
-		 * reservation head and the tail.  The bytes accounted for
-		 * by the l_roundoff field are temporarily 'lost' to the
-		 * reservation mechanism, but they are cleaned up when the
-		 * log buffers that created them are reused.  These lost
-		 * bytes are what allow the reservation head to fall behind
-		 * the tail in the case that the log is 'empty'.
 		 * In this case we just want to return the size of the
 		 * log as the amount of space left.
 		 */
-		ASSERT((tail_cycle == (cycle + 1)) ||
-		       ((bytes + log->l_roundoff) >= tail_bytes));
+		xfs_fs_cmn_err(CE_ALERT, log->l_mp,
+			"xlog_space_left: head behind tail\n"
+			"  tail_cycle = %d, tail_bytes = %d\n"
+			"  GH   cycle = %d, GH   bytes = %d",
+			tail_cycle, tail_bytes, cycle, bytes);
+		ASSERT(0);
 		free_bytes = log->l_logsize;
 	}
 	return free_bytes;
@@ -1355,8 +1350,8 @@ xlog_grant_push_ail(xfs_mount_t	*mp,
 
 
 /*
- * Flush out the in-core log (iclog) to the on-disk log in a synchronous or
- * asynchronous fashion.  Previously, we should have moved the current iclog
+ * Flush out the in-core log (iclog) to the on-disk log in an asynchronous 
+ * fashion.  Previously, we should have moved the current iclog
  * ptr in the log to point to the next available iclog.  This allows further
  * write to continue while this code syncs out an iclog ready to go.
  * Before an in-core log can be written out, the data section must be scanned
@@ -1388,8 +1383,11 @@ xlog_sync(xlog_t		*log,
 	int		i, ops;
 	uint		count;		/* byte count of bwrite */
 	uint		count_init;	/* initial count before roundup */
+	int		roundoff;       /* roundoff to BB or stripe */
 	int		split = 0;	/* split write into two regions */
 	int		error;
+	SPLDECL(s);
+	int		v2 = XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb);
 
 	XFS_STATS_INC(xs_log_writes);
 	ASSERT(iclog->ic_refcnt == 0);
@@ -1398,23 +1396,34 @@ xlog_sync(xlog_t		*log,
 	count_init = log->l_iclog_hsize + iclog->ic_offset;
 
 	/* Round out the log write size */
-	if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) &&
-	    log->l_mp->m_sb.sb_logsunit > 1) {
+	if (v2 && log->l_mp->m_sb.sb_logsunit > 1) {
 		/* we have a v2 stripe unit to use */
 		count = XLOG_LSUNITTOB(log, XLOG_BTOLSUNIT(log, count_init));
 	} else {
 		count = BBTOB(BTOBB(count_init));
 	}
-	iclog->ic_roundoff = count - count_init;
-	log->l_roundoff += iclog->ic_roundoff;
+	roundoff = count - count_init;
+	ASSERT(roundoff >= 0);
+	ASSERT((v2 && log->l_mp->m_sb.sb_logsunit > 1 && 
+                roundoff < log->l_mp->m_sb.sb_logsunit)
+		|| 
+		(log->l_mp->m_sb.sb_logsunit <= 1 && 
+		 roundoff < BBTOB(1)));
 
-	xlog_pack_data(log, iclog);       /* put cycle number in every block */
+	/* move grant heads by roundoff in sync */
+	s = GRANT_LOCK(log);
+	XLOG_GRANT_ADD_SPACE(log, roundoff, 'w');
+	XLOG_GRANT_ADD_SPACE(log, roundoff, 'r');
+	GRANT_UNLOCK(log, s);
+
+	/* put cycle number in every block */
+	xlog_pack_data(log, iclog, roundoff); 
 
 	/* real byte length */
-	if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
+	if (v2) {
 		INT_SET(iclog->ic_header.h_len, 
 			ARCH_CONVERT,
-			iclog->ic_offset + iclog->ic_roundoff);
+			iclog->ic_offset + roundoff);
 	} else {
 		INT_SET(iclog->ic_header.h_len, ARCH_CONVERT, iclog->ic_offset);
 	}
@@ -2278,11 +2287,6 @@ restart:
 		INT_SET(head->h_cycle, ARCH_CONVERT, log->l_curr_cycle);
 		ASSIGN_LSN(head->h_lsn, log, ARCH_CONVERT);
 		ASSERT(log->l_curr_block >= 0);
-
-		/* round off error from last write with this iclog */
-		ticket->t_curr_res -= iclog->ic_roundoff;
-		log->l_roundoff -= iclog->ic_roundoff;
-		iclog->ic_roundoff = 0;
 	}
 
 	/* If there is enough room to write everything, then do it.  Otherwise,
@@ -2853,7 +2857,6 @@ xlog_state_sync_all(xlog_t *log, uint fl
 				 * has already taken care of the roundoff from
 				 * the previous sync.
 				 */
-				ASSERT(iclog->ic_roundoff == 0);
 				iclog->ic_refcnt++;
 				lsn = INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT);
 				xlog_state_switch_iclogs(log, iclog, 0);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/xfs_log_priv.h linux-2.4.29-pre3/fs/xfs/xfs_log_priv.h
--- linux-2.4.28/fs/xfs/xfs_log_priv.h	2004-04-14 13:05:40.000000000 +0000
+++ linux-2.4.29-pre3/fs/xfs/xfs_log_priv.h	2004-12-22 16:06:04.781571032 +0000
@@ -430,7 +430,6 @@ typedef struct xlog_iclog_fields {
 	int			ic_size;
 	int			ic_offset;
 	int			ic_refcnt;
-	int			ic_roundoff;
 	int			ic_bwritecnt;
 	ushort_t		ic_state;
 	char			*ic_datap;	/* pointer to iclog data */
@@ -462,7 +461,6 @@ typedef struct xlog_in_core {
 #define	ic_size		hic_fields.ic_size
 #define	ic_offset	hic_fields.ic_offset
 #define	ic_refcnt	hic_fields.ic_refcnt
-#define	ic_roundoff	hic_fields.ic_roundoff
 #define	ic_bwritecnt	hic_fields.ic_bwritecnt
 #define	ic_state	hic_fields.ic_state
 #define ic_datap	hic_fields.ic_datap
@@ -498,7 +496,6 @@ typedef struct log {
 	xfs_daddr_t		l_logBBstart;   /* start block of log */
 	int			l_logsize;      /* size of log in bytes */
 	int			l_logBBsize;    /* size of log in BB chunks */
-	int			l_roundoff;	/* round off error of iclogs */
 	int			l_curr_cycle;   /* Cycle number of log writes */
 	int			l_prev_cycle;   /* Cycle number before last
 						 * block increment */
@@ -543,10 +540,9 @@ extern int	 xlog_find_tail(xlog_t	*log,
 				xfs_daddr_t *head_blk,
 				xfs_daddr_t *tail_blk,
 				int readonly);
-extern int	 xlog_print_find_oldest(xlog_t *log, xfs_daddr_t *last_blk);
 extern int	 xlog_recover(xlog_t *log, int readonly);
 extern int	 xlog_recover_finish(xlog_t *log, int mfsi_flags);
-extern void	 xlog_pack_data(xlog_t *log, xlog_in_core_t *iclog);
+extern void	 xlog_pack_data(xlog_t *log, xlog_in_core_t *iclog, int);
 extern void	 xlog_recover_process_iunlinks(xlog_t *log);
 
 extern struct xfs_buf *xlog_get_bp(xlog_t *, int);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/xfs_log_recover.c linux-2.4.29-pre3/fs/xfs/xfs_log_recover.c
--- linux-2.4.28/fs/xfs/xfs_log_recover.c	2004-12-22 16:17:19.940931208 +0000
+++ linux-2.4.29-pre3/fs/xfs/xfs_log_recover.c	2004-12-22 16:07:36.466632784 +0000
@@ -3262,7 +3262,7 @@ xlog_recover_process_iunlinks(
 				xfs_buf_relse(agibp);
 
 				ino = XFS_AGINO_TO_INO(mp, agno, agino);
-				error = xfs_iget(mp, NULL, ino, 0, &ip, 0);
+				error = xfs_iget(mp, NULL, ino, 0, 0, &ip, 0);
 				ASSERT(error || (ip != NULL));
 
 				if (!error) {
@@ -3384,10 +3384,11 @@ xlog_pack_data_checksum(
 void
 xlog_pack_data(
 	xlog_t			*log,
-	xlog_in_core_t		*iclog)
+	xlog_in_core_t		*iclog,
+	int			roundoff)
 {
 	int			i, j, k;
-	int			size = iclog->ic_offset + iclog->ic_roundoff;
+	int			size = iclog->ic_offset + roundoff;
 	uint			cycle_lsn;
 	xfs_caddr_t		dp;
 	xlog_in_core_2_t	*xhdr;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/xfs_mac.c linux-2.4.29-pre3/fs/xfs/xfs_mac.c
--- linux-2.4.28/fs/xfs/xfs_mac.c	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/fs/xfs/xfs_mac.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like.  Any license provided herein, whether implied or
- * otherwise, applies only to this software file.  Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA  94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
- */
-
-#include "xfs.h"
-
-static xfs_mac_label_t *mac_low_high_lp;
-static xfs_mac_label_t *mac_high_low_lp;
-static xfs_mac_label_t *mac_admin_high_lp;
-static xfs_mac_label_t *mac_equal_equal_lp;
-
-/*
- * Test for the existence of a MAC label as efficiently as possible.
- */
-int
-xfs_mac_vhaslabel(
-	vnode_t		*vp)
-{
-	int		error;
-	int		len = sizeof(xfs_mac_label_t);
-	int		flags = ATTR_KERNOVAL|ATTR_ROOT;
-
-	VOP_ATTR_GET(vp, SGI_MAC_FILE, NULL, &len, flags, sys_cred, error);
-	return (error == 0);
-}
-
-int
-xfs_mac_iaccess(xfs_inode_t *ip, mode_t mode, struct cred *cr)
-{
-	xfs_mac_label_t mac;
-	xfs_mac_label_t *mp = mac_high_low_lp;
-
-	if (cr == NULL || sys_cred == NULL ) {
-		return EACCES;
-	}
-
-	if (xfs_attr_fetch(ip, SGI_MAC_FILE, (char *)&mac, sizeof(mac)) == 0) {
-		if ((mp = mac_add_label(&mac)) == NULL) {
-			return mac_access(mac_high_low_lp, cr, mode);
-		}
-	}
-
-	return mac_access(mp, cr, mode);
-}
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/xfs_mount.c linux-2.4.29-pre3/fs/xfs/xfs_mount.c
--- linux-2.4.28/fs/xfs/xfs_mount.c	2004-12-22 16:17:19.955928928 +0000
+++ linux-2.4.29-pre3/fs/xfs/xfs_mount.c	2004-12-22 16:07:14.702941368 +0000
@@ -975,7 +975,7 @@ xfs_mountfs(
 	 * Get and sanity-check the root inode.
 	 * Save the pointer to it in the mount structure.
 	 */
-	error = xfs_iget(mp, NULL, sbp->sb_rootino, XFS_ILOCK_EXCL, &rip, 0);
+	error = xfs_iget(mp, NULL, sbp->sb_rootino, 0, XFS_ILOCK_EXCL, &rip, 0);
 	if (error) {
 		cmn_err(CE_WARN, "XFS: failed to read root inode");
 		goto error3;
@@ -1036,7 +1036,7 @@ xfs_mountfs(
 	/*
 	 * Complete the quota initialisation, post-log-replay component.
 	 */
-	if ((error = XFS_QM_MOUNT(mp, quotamount, quotaflags)))
+	if ((error = XFS_QM_MOUNT(mp, quotamount, quotaflags, mfsi_flags)))
 		goto error4;
 
 	return 0;
@@ -1098,6 +1098,8 @@ xfs_unmountfs(xfs_mount_t *mp, struct cr
 
 	xfs_unmountfs_writesb(mp);
 
+	xfs_unmountfs_wait(mp); 		/* wait for async bufs */
+
 	xfs_log_unmount(mp);			/* Done! No more fs ops. */
 
 	xfs_freesb(mp);
@@ -1142,6 +1144,16 @@ xfs_unmountfs_close(xfs_mount_t *mp, str
 	xfs_free_buftarg(mp->m_ddev_targp, 0);
 }
 
+void
+xfs_unmountfs_wait(xfs_mount_t *mp)
+{
+	if (mp->m_logdev_targp != mp->m_ddev_targp)
+		xfs_wait_buftarg(mp->m_logdev_targp);
+	if (mp->m_rtdev_targp)
+		xfs_wait_buftarg(mp->m_rtdev_targp);
+	xfs_wait_buftarg(mp->m_ddev_targp);
+}
+
 int
 xfs_unmountfs_writesb(xfs_mount_t *mp)
 {
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/xfs_mount.h linux-2.4.29-pre3/fs/xfs/xfs_mount.h
--- linux-2.4.28/fs/xfs/xfs_mount.h	2004-12-22 16:17:19.961928016 +0000
+++ linux-2.4.29-pre3/fs/xfs/xfs_mount.h	2004-12-22 16:05:48.976973696 +0000
@@ -133,7 +133,7 @@ struct xfs_dqtrxops;
 struct xfs_quotainfo;
 
 typedef int	(*xfs_qminit_t)(struct xfs_mount *, uint *, uint *);
-typedef int	(*xfs_qmmount_t)(struct xfs_mount *, uint, uint);
+typedef int	(*xfs_qmmount_t)(struct xfs_mount *, uint, uint, int);
 typedef int	(*xfs_qmunmount_t)(struct xfs_mount *);
 typedef void	(*xfs_qmdone_t)(struct xfs_mount *);
 typedef void	(*xfs_dqrele_t)(struct xfs_dquot *);
@@ -171,8 +171,8 @@ typedef struct xfs_qmops {
 
 #define XFS_QM_INIT(mp, mnt, fl) \
 	(*(mp)->m_qm_ops.xfs_qminit)(mp, mnt, fl)
-#define XFS_QM_MOUNT(mp, mnt, fl) \
-	(*(mp)->m_qm_ops.xfs_qmmount)(mp, mnt, fl)
+#define XFS_QM_MOUNT(mp, mnt, fl, mfsi_flags) \
+	(*(mp)->m_qm_ops.xfs_qmmount)(mp, mnt, fl, mfsi_flags)
 #define XFS_QM_UNMOUNT(mp) \
 	(*(mp)->m_qm_ops.xfs_qmunmount)(mp)
 #define XFS_QM_DONE(mp) \
@@ -466,6 +466,7 @@ typedef struct xfs_mount {
 #define XFS_MFSI_CLIENT		0x02	/* Is a client -- skip lots of stuff */
 #define XFS_MFSI_NOUNLINK	0x08	/* Skip unlinked inode processing in */
 					/* log recovery */
+#define XFS_MFSI_NO_QUOTACHECK	0x10	/* Skip quotacheck processing */
 
 /*
  * Macros for getting from mount to vfs and back.
@@ -540,6 +541,7 @@ extern void	xfs_mount_free(xfs_mount_t *
 extern int	xfs_mountfs(struct vfs *, xfs_mount_t *mp, int);
 
 extern int	xfs_unmountfs(xfs_mount_t *, struct cred *);
+extern void	xfs_unmountfs_wait(xfs_mount_t *);
 extern void	xfs_unmountfs_close(xfs_mount_t *, struct cred *);
 extern int	xfs_unmountfs_writesb(xfs_mount_t *);
 extern int	xfs_unmount_flush(xfs_mount_t *, int);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/xfs_rtalloc.c linux-2.4.29-pre3/fs/xfs/xfs_rtalloc.c
--- linux-2.4.28/fs/xfs/xfs_rtalloc.c	2004-12-22 16:17:19.986924216 +0000
+++ linux-2.4.29-pre3/fs/xfs/xfs_rtalloc.c	2004-12-22 16:06:05.073526648 +0000
@@ -149,7 +149,7 @@ xfs_growfs_rt_alloc(
 		/*
 		 * Lock the inode.
 		 */
-		if ((error = xfs_trans_iget(mp, tp, ino, XFS_ILOCK_EXCL, &ip)))
+		if ((error = xfs_trans_iget(mp, tp, ino, 0, XFS_ILOCK_EXCL, &ip)))
 			goto error_exit;
 		XFS_BMAP_INIT(&flist, &firstblock);
 		/*
@@ -189,7 +189,7 @@ xfs_growfs_rt_alloc(
 			/*
 			 * Lock the bitmap inode.
 			 */
-			if ((error = xfs_trans_iget(mp, tp, ino, XFS_ILOCK_EXCL,
+			if ((error = xfs_trans_iget(mp, tp, ino, 0, XFS_ILOCK_EXCL,
 					&ip)))
 				goto error_exit;
 			/*
@@ -1966,7 +1966,8 @@ xfs_growfs_rt(
 	/*
 	 * Calculate new parameters.  These are the final values to be reached.
 	 */
-	nrextents = do_div(nrblocks, in->extsize);
+	nrextents = nrblocks;
+	do_div(nrextents, in->extsize);
 	nrbmblocks = roundup_64(nrextents, NBBY * sbp->sb_blocksize);
 	nrextslog = xfs_highbit32(nrextents);
 	nrsumlevels = nrextslog + 1;
@@ -2021,7 +2022,8 @@ xfs_growfs_rt(
 			XFS_RTMIN(nrblocks,
 				  nsbp->sb_rbmblocks * NBBY *
 				  nsbp->sb_blocksize * nsbp->sb_rextsize);
-		nsbp->sb_rextents = do_div(nsbp->sb_rblocks, nsbp->sb_rextsize);
+		nsbp->sb_rextents = nsbp->sb_rblocks;
+		do_div(nsbp->sb_rextents, nsbp->sb_rextsize);
 		nsbp->sb_rextslog = xfs_highbit32(nsbp->sb_rextents);
 		nrsumlevels = nmp->m_rsumlevels = nsbp->sb_rextslog + 1;
 		nrsumsize =
@@ -2040,7 +2042,7 @@ xfs_growfs_rt(
 		/*
 		 * Lock out other callers by grabbing the bitmap inode lock.
 		 */
-		if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino,
+		if ((error = xfs_trans_iget(mp, tp, 0, mp->m_sb.sb_rbmino,
 				XFS_ILOCK_EXCL, &ip)))
 			goto error_exit;
 		ASSERT(ip == mp->m_rbmip);
@@ -2055,7 +2057,7 @@ xfs_growfs_rt(
 		 * Get the summary inode into the transaction.
 		 */
 		if ((error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rsumino,
-				XFS_ILOCK_EXCL, &ip)))
+				0, XFS_ILOCK_EXCL, &ip)))
 			goto error_exit;
 		ASSERT(ip == mp->m_rsumip);
 		/*
@@ -2175,7 +2177,7 @@ xfs_rtallocate_extent(
 	/*
 	 * Lock out other callers by grabbing the bitmap inode lock.
 	 */
-	error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, XFS_ILOCK_EXCL, &ip);
+	error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0, XFS_ILOCK_EXCL, &ip);
 	if (error) {
 		return error;
 	}
@@ -2238,7 +2240,7 @@ xfs_rtfree_extent(
 	/*
 	 * Synchronize by locking the bitmap inode.
 	 */
-	error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, XFS_ILOCK_EXCL, &ip);
+	error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0, XFS_ILOCK_EXCL, &ip);
 	if (error) {
 		return error;
 	}
@@ -2346,12 +2348,12 @@ xfs_rtmount_inodes(
 	sbp = &mp->m_sb;
 	if (sbp->sb_rbmino == NULLFSINO)
 		return 0;
-	error = xfs_iget(mp, NULL, sbp->sb_rbmino, 0, &mp->m_rbmip, 0);
+	error = xfs_iget(mp, NULL, sbp->sb_rbmino, 0, 0, &mp->m_rbmip, 0);
 	if (error)
 		return error;
 	ASSERT(mp->m_rbmip != NULL);
 	ASSERT(sbp->sb_rsumino != NULLFSINO);
-	error = xfs_iget(mp, NULL, sbp->sb_rsumino, 0, &mp->m_rsumip, 0);
+	error = xfs_iget(mp, NULL, sbp->sb_rsumino, 0, 0, &mp->m_rsumip, 0);
 	if (error) {
 		VN_RELE(XFS_ITOV(mp->m_rbmip));
 		return error;
@@ -2382,7 +2384,7 @@ xfs_rtpick_extent(
 	__uint64_t	seq;		/* sequence number of file creation */
 	__uint64_t	*seqp;		/* pointer to seqno in inode */
 
-	error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, XFS_ILOCK_EXCL, &ip);
+	error = xfs_trans_iget(mp, tp, mp->m_sb.sb_rbmino, 0, XFS_ILOCK_EXCL, &ip);
 	if (error)
 		return error;
 	ASSERT(ip == mp->m_rbmip);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/xfs_trans.h linux-2.4.29-pre3/fs/xfs/xfs_trans.h
--- linux-2.4.28/fs/xfs/xfs_trans.h	2004-08-07 23:26:06.000000000 +0000
+++ linux-2.4.29-pre3/fs/xfs/xfs_trans.h	2004-12-22 16:07:51.289379384 +0000
@@ -1007,7 +1007,7 @@ void		xfs_trans_stale_inode_buf(xfs_tran
 void		xfs_trans_dquot_buf(xfs_trans_t *, struct xfs_buf *, uint);
 void		xfs_trans_inode_alloc_buf(xfs_trans_t *, struct xfs_buf *);
 int		xfs_trans_iget(struct xfs_mount *, xfs_trans_t *,
-			       xfs_ino_t , uint, struct xfs_inode **);
+			       xfs_ino_t , uint, uint, struct xfs_inode **);
 void		xfs_trans_ijoin(xfs_trans_t *, struct xfs_inode *, uint);
 void		xfs_trans_ihold(xfs_trans_t *, struct xfs_inode *);
 void		xfs_trans_ihold_release(xfs_trans_t *, struct xfs_inode *);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/xfs_trans_inode.c linux-2.4.29-pre3/fs/xfs/xfs_trans_inode.c
--- linux-2.4.28/fs/xfs/xfs_trans_inode.c	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/fs/xfs/xfs_trans_inode.c	2004-12-22 16:05:32.556469992 +0000
@@ -95,6 +95,7 @@ xfs_trans_iget(
 	xfs_mount_t	*mp,
 	xfs_trans_t	*tp,
 	xfs_ino_t	ino,
+	uint		flags,
 	uint		lock_flags,
 	xfs_inode_t	**ipp)
 {
@@ -106,9 +107,8 @@ xfs_trans_iget(
 	 * If the transaction pointer is NULL, just call the normal
 	 * xfs_iget().
 	 */
-	if (tp == NULL) {
-		return (xfs_iget(mp, NULL, ino, lock_flags, ipp, 0));
-	}
+	if (tp == NULL)
+		return xfs_iget(mp, NULL, ino, flags, lock_flags, ipp, 0);
 
 	/*
 	 * If we find the inode in core with this transaction
@@ -148,7 +148,7 @@ xfs_trans_iget(
 	}
 
 	ASSERT(lock_flags & XFS_ILOCK_EXCL);
-	error = xfs_iget(tp->t_mountp, tp, ino, lock_flags, &ip, 0);
+	error = xfs_iget(tp->t_mountp, tp, ino, flags, lock_flags, &ip, 0);
 	if (error) {
 		return error;
 	}
@@ -186,7 +186,6 @@ xfs_trans_iget(
 	return 0;
 }
 
-
 /*
  * Add the locked inode to the transaction.
  * The inode must be locked, and it cannot be associated with any
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/xfs_utils.c linux-2.4.29-pre3/fs/xfs/xfs_utils.c
--- linux-2.4.28/fs/xfs/xfs_utils.c	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/fs/xfs/xfs_utils.c	2004-12-22 16:06:28.908903120 +0000
@@ -110,7 +110,7 @@ xfs_dir_lookup_int(
 		 * reservation in the inactive routine.
 		 */
 		xfs_iunlock(dp, lock_mode);
-		error = xfs_iget(dp->i_mount, NULL, *inum, 0, ipp, 0);
+		error = xfs_iget(dp->i_mount, NULL, *inum, 0, 0, ipp, 0);
 		xfs_ilock(dp, lock_mode);
 
 		if (error) {
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/xfs_vfsops.c linux-2.4.29-pre3/fs/xfs/xfs_vfsops.c
--- linux-2.4.28/fs/xfs/xfs_vfsops.c	2004-12-22 16:17:20.045915248 +0000
+++ linux-2.4.29-pre3/fs/xfs/xfs_vfsops.c	2004-12-22 16:07:05.481343264 +0000
@@ -1053,6 +1053,11 @@ xfs_sync_inodes(
 			continue;
 		}
 
+		if (VN_BAD(vp)) {
+			ip = ip->i_mnext;
+			continue;
+		}
+
 		if (XFS_FORCED_SHUTDOWN(mp) && !(flags & SYNC_CLOSE)) {
 			XFS_MOUNT_IUNLOCK(mp);
 			kmem_free(ipointer, sizeof(xfs_iptr_t));
@@ -1583,31 +1588,35 @@ xfs_vget(
 	vnode_t		**vpp,
 	fid_t		*fidp)
 {
-	xfs_fid_t	*xfid;
+	xfs_mount_t	*mp = XFS_BHVTOM(bdp);
+	xfs_fid_t	*xfid = (struct xfs_fid *)fidp;
 	xfs_inode_t	*ip;
 	int		error;
 	xfs_ino_t	ino;
 	unsigned int	igen;
-	xfs_mount_t	*mp;
 
-	xfid  = (struct xfs_fid *)fidp;
-	if (xfid->xfs_fid_len == sizeof(*xfid) - sizeof(xfid->xfs_fid_len)) {
-		ino  = xfid->xfs_fid_ino;
-		igen = xfid->xfs_fid_gen;
-	} else {
-		/*
-		 * Invalid.  Since handles can be created in user space
-		 * and passed in via gethandle(), this is not cause for
-		 * a panic.
-		 */
+	/*
+	 * Invalid.  Since handles can be created in user space and passed in
+	 * via gethandle(), this is not cause for a panic.
+	 */
+	if (xfid->xfs_fid_len != sizeof(*xfid) - sizeof(xfid->xfs_fid_len))
 		return XFS_ERROR(EINVAL);
-	}
-	mp = XFS_BHVTOM(bdp);
-	error = xfs_iget(mp, NULL, ino, XFS_ILOCK_SHARED, &ip, 0);
+
+	ino  = xfid->xfs_fid_ino;
+	igen = xfid->xfs_fid_gen;
+
+	/*
+	 * NFS can sometimes send requests for ino 0.  Fail them gracefully.
+	 */
+	if (ino == 0)
+		return XFS_ERROR(ESTALE);
+
+	error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, 0);
 	if (error) {
 		*vpp = NULL;
 		return error;
 	}
+
 	if (ip == NULL) {
 		*vpp = NULL;
 		return XFS_ERROR(EIO);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/fs/xfs/xfs_vnodeops.c linux-2.4.29-pre3/fs/xfs/xfs_vnodeops.c
--- linux-2.4.28/fs/xfs/xfs_vnodeops.c	2004-12-22 16:17:20.257883024 +0000
+++ linux-2.4.29-pre3/fs/xfs/xfs_vnodeops.c	2004-12-22 16:07:06.325214976 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -826,29 +826,34 @@ xfs_setattr(
 				mp->m_sb.sb_blocklog;
 		}
 		if (mask & XFS_AT_XFLAGS) {
+			uint	di_flags;
+
 			/* can't set PREALLOC this way, just preserve it */
-			ip->i_d.di_flags =
-				(ip->i_d.di_flags & XFS_DIFLAG_PREALLOC);
-			if (vap->va_xflags & XFS_XFLAG_REALTIME &&
-			    (ip->i_d.di_mode & S_IFMT) == S_IFREG) {
-				ip->i_d.di_flags |= XFS_DIFLAG_REALTIME;
-				ip->i_iocore.io_flags |= XFS_IOCORE_RT;
-			} else {
-				ip->i_iocore.io_flags &= ~XFS_IOCORE_RT;
-			}
+			di_flags = (ip->i_d.di_flags & XFS_DIFLAG_PREALLOC);
 			if (vap->va_xflags & XFS_XFLAG_IMMUTABLE)
-				ip->i_d.di_flags |= XFS_DIFLAG_IMMUTABLE;
+				di_flags |= XFS_DIFLAG_IMMUTABLE;
 			if (vap->va_xflags & XFS_XFLAG_APPEND)
-				ip->i_d.di_flags |= XFS_DIFLAG_APPEND;
+				di_flags |= XFS_DIFLAG_APPEND;
 			if (vap->va_xflags & XFS_XFLAG_SYNC)
-				ip->i_d.di_flags |= XFS_DIFLAG_SYNC;
+				di_flags |= XFS_DIFLAG_SYNC;
 			if (vap->va_xflags & XFS_XFLAG_NOATIME)
-				ip->i_d.di_flags |= XFS_DIFLAG_NOATIME;
+				di_flags |= XFS_DIFLAG_NOATIME;
 			if (vap->va_xflags & XFS_XFLAG_NODUMP)
-				ip->i_d.di_flags |= XFS_DIFLAG_NODUMP;
-			if ((vap->va_xflags & XFS_XFLAG_RTINHERIT) &&
-			    (ip->i_d.di_mode & S_IFMT) == S_IFDIR)
-				ip->i_d.di_flags |= XFS_DIFLAG_RTINHERIT;
+				di_flags |= XFS_DIFLAG_NODUMP;
+			if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) {
+				if (vap->va_xflags & XFS_XFLAG_RTINHERIT)
+					di_flags |= XFS_DIFLAG_RTINHERIT;
+				if (vap->va_xflags & XFS_XFLAG_NOSYMLINKS)
+					di_flags |= XFS_DIFLAG_NOSYMLINKS;
+			} else {
+				if (vap->va_xflags & XFS_XFLAG_REALTIME) {
+					di_flags |= XFS_DIFLAG_REALTIME;
+					ip->i_iocore.io_flags |= XFS_IOCORE_RT;
+				} else {
+					ip->i_iocore.io_flags &= ~XFS_IOCORE_RT;
+				}
+			}
+			ip->i_d.di_flags = di_flags;
 		}
 		xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
 		timeflags |= XFS_ICHGTIME_CHG;
@@ -1606,7 +1611,7 @@ xfs_inactive(
 	 * If the inode is already free, then there can be nothing
 	 * to clean up here.
 	 */
-	if (ip->i_d.di_mode == 0) {
+	if (ip->i_d.di_mode == 0 || VN_BAD(vp)) {
 		ASSERT(ip->i_df.if_real_bytes == 0);
 		ASSERT(ip->i_df.if_broot_bytes == 0);
 		return VN_INACTIVE_CACHE;
@@ -3390,6 +3395,14 @@ xfs_symlink(
 	xfs_ilock(dp, XFS_ILOCK_EXCL);
 
 	/*
+	 * Check whether the directory allows new symlinks or not.
+	 */
+	if (dp->i_d.di_flags & XFS_DIFLAG_NOSYMLINKS) {
+		error = XFS_ERROR(EPERM);
+		goto error_return;
+	}
+
+	/*
 	 * Reserve disk quota : blocks and inode.
 	 */
 	error = XFS_TRANS_RESERVE_QUOTA(mp, tp, udqp, gdqp, resblks, 1, 0);
@@ -3795,11 +3808,17 @@ xfs_reclaim(
 	vnode_t		*vp;
 
 	vp = BHV_TO_VNODE(bdp);
+	ip = XFS_BHVTOI(bdp);
 
 	vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
 
 	ASSERT(!VN_MAPPED(vp));
-	ip = XFS_BHVTOI(bdp);
+
+	/* bad inode, get out here ASAP */
+	if (VN_BAD(vp)) {
+		xfs_ireclaim(ip);
+		return 0;
+	}
 
 	if ((ip->i_d.di_mode & S_IFMT) == S_IFREG) {
 		if (ip->i_d.di_size > 0) {
@@ -3877,8 +3896,12 @@ xfs_finish_reclaim(
 	int		sync_mode)
 {
 	xfs_ihash_t	*ih = ip->i_hash;
+	vnode_t		*vp = XFS_ITOV_NULL(ip);
 	int		error;
 
+	if (vp && VN_BAD(vp))
+		return 0;
+
 	/* The hash lock here protects a thread in xfs_iget_core from
 	 * racing with us on linking the inode back with a vnode.
 	 * Once we have the XFS_IRECLAIM flag set it will not touch
@@ -3886,8 +3909,7 @@ xfs_finish_reclaim(
 	 */
 	write_lock(&ih->ih_lock);
 	if ((ip->i_flags & XFS_IRECLAIM) ||
-	    (!(ip->i_flags & XFS_IRECLAIMABLE) &&
-	      (XFS_ITOV_NULL(ip) == NULL))) {
+	    (!(ip->i_flags & XFS_IRECLAIMABLE) && vp == NULL)) {
 		write_unlock(&ih->ih_lock);
 		if (locked) {
 			xfs_ifunlock(ip);
@@ -3954,15 +3976,13 @@ int
 xfs_finish_reclaim_all(xfs_mount_t *mp, int noblock)
 {
 	int		purged;
-	struct list_head	*curr, *next;
-	xfs_inode_t	*ip;
+	xfs_inode_t	*ip, *n;
 	int		done = 0;
 
 	while (!done) {
 		purged = 0;
 		XFS_MOUNT_ILOCK(mp);
-		list_for_each_safe(curr, next, &mp->m_del_inodes) {
-			ip = list_entry(curr, xfs_inode_t, i_reclaim);
+		list_for_each_entry_safe(ip, n, &mp->m_del_inodes, i_reclaim) {
 			if (noblock) {
 				if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL) == 0)
 					continue;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/au1000.h linux-2.4.29-pre3/include/asm-mips/au1000.h
--- linux-2.4.28/include/asm-mips/au1000.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/au1000.h	2004-12-22 16:05:32.000000000 +0000
@@ -161,6 +161,7 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
 #endif
 
 /* SDRAM Controller */
+#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1100)
 #define MEM_SDMODE0                0xB4000000
 #define MEM_SDMODE1                0xB4000004
 #define MEM_SDMODE2                0xB4000008
@@ -179,6 +180,7 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
 
 #define MEM_SDSLEEP                0xB4000030
 #define MEM_SDSMCKE                0xB4000034
+#endif
 
 /* Static Bus Controller */
 #define MEM_STCFG0                 0xB4001000
@@ -197,6 +199,15 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
 #define MEM_STTIME3                0xB4001034
 #define MEM_STADDR3                0xB4001038
 
+#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
+#define MEM_STNDCTL                0xB4001100
+#define MEM_STSTAT                 0xB4001104
+
+#define MEM_STNAND_CMD                  (0x0)
+#define MEM_STNAND_ADDR                 (0x4)
+#define MEM_STNAND_DATA                (0x20)
+#endif
+
 /* Interrupt Controller 0 */
 #define IC0_CFG0RD                 0xB0400040
 #define IC0_CFG0SET                0xB0400040
@@ -283,21 +294,14 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
 #define INTC_INT_HIGH_AND_LOW_LEVEL    0x7
 
 /* Interrupt Numbers */
+/* Au1000 */
+#ifdef CONFIG_SOC_AU1000
 #define AU1000_UART0_INT          0
 #define AU1000_UART1_INT          1 /* au1000 */
 #define AU1000_UART2_INT          2 /* au1000 */
-
-#define AU1000_PCI_INTA           1 /* au1500 */
-#define AU1000_PCI_INTB           2 /* au1500 */
-
 #define AU1000_UART3_INT          3
-
 #define AU1000_SSI0_INT           4 /* au1000 */
 #define AU1000_SSI1_INT           5 /* au1000 */
-
-#define AU1000_PCI_INTC           4 /* au1500 */
-#define AU1000_PCI_INTD           5 /* au1500 */
-
 #define AU1000_DMA_INT_BASE       6
 #define AU1000_TOY_INT            14
 #define AU1000_TOY_MATCH0_INT     15
@@ -315,11 +319,8 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
 #define AU1000_ACSYNC_INT         27
 #define AU1000_MAC0_DMA_INT       28
 #define AU1000_MAC1_DMA_INT       29
-#define AU1000_ETH0_IRQ           AU1000_MAC0_DMA_INT
-#define AU1000_ETH1_IRQ           AU1000_MAC1_DMA_INT
 #define AU1000_I2S_UO_INT         30 /* au1000 */
 #define AU1000_AC97C_INT          31
-#define AU1000_LAST_INTC0_INT     AU1000_AC97C_INT
 #define AU1000_GPIO_0             32
 #define AU1000_GPIO_1             33
 #define AU1000_GPIO_2             34
@@ -336,8 +337,6 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
 #define AU1000_GPIO_13            45
 #define AU1000_GPIO_14            46
 #define AU1000_GPIO_15            47
-
-/* Au1000 only */
 #define AU1000_GPIO_16            48
 #define AU1000_GPIO_17            49
 #define AU1000_GPIO_18            50
@@ -355,7 +354,62 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
 #define AU1000_GPIO_30            62
 #define AU1000_GPIO_31            63
 
-/* Au1500 only */
+#define UART0_ADDR                0xB1100000
+#define UART1_ADDR                0xB1200000
+#define UART2_ADDR                0xB1300000
+#define UART3_ADDR                0xB1400000
+
+#define USB_OHCI_BASE             0x10100000 // phys addr for ioremap
+#define USB_HOST_CONFIG           0xB017fffc
+
+#define AU1000_ETH0_BASE      0xB0500000
+#define AU1000_ETH1_BASE      0xB0510000
+#define AU1000_MAC0_ENABLE       0xB0520000
+#define AU1000_MAC1_ENABLE       0xB0520004
+#define NUM_ETH_INTERFACES 2
+#endif // CONFIG_SOC_AU1000
+
+/* Au1500 */
+#ifdef CONFIG_SOC_AU1500
+#define AU1500_UART0_INT          0
+#define AU1000_PCI_INTA           1 /* au1500 */
+#define AU1000_PCI_INTB           2 /* au1500 */
+#define AU1500_UART3_INT          3
+#define AU1000_PCI_INTC           4 /* au1500 */
+#define AU1000_PCI_INTD           5 /* au1500 */
+#define AU1000_DMA_INT_BASE       6
+#define AU1000_TOY_INT            14
+#define AU1000_TOY_MATCH0_INT     15
+#define AU1000_TOY_MATCH1_INT     16
+#define AU1000_TOY_MATCH2_INT     17
+#define AU1000_RTC_INT            18
+#define AU1000_RTC_MATCH0_INT     19
+#define AU1000_RTC_MATCH1_INT     20
+#define AU1000_RTC_MATCH2_INT     21
+#define AU1500_PCI_ERR_INT        22
+#define AU1000_USB_DEV_REQ_INT    24
+#define AU1000_USB_DEV_SUS_INT    25
+#define AU1000_USB_HOST_INT       26
+#define AU1000_ACSYNC_INT         27
+#define AU1500_MAC0_DMA_INT       28
+#define AU1500_MAC1_DMA_INT       29
+#define AU1000_AC97C_INT          31
+#define AU1000_GPIO_0             32
+#define AU1000_GPIO_1             33
+#define AU1000_GPIO_2             34
+#define AU1000_GPIO_3             35
+#define AU1000_GPIO_4             36
+#define AU1000_GPIO_5             37
+#define AU1000_GPIO_6             38
+#define AU1000_GPIO_7             39
+#define AU1000_GPIO_8             40
+#define AU1000_GPIO_9             41
+#define AU1000_GPIO_10            42
+#define AU1000_GPIO_11            43
+#define AU1000_GPIO_12            44
+#define AU1000_GPIO_13            45
+#define AU1000_GPIO_14            46
+#define AU1000_GPIO_15            47
 #define AU1500_GPIO_200           48
 #define AU1500_GPIO_201           49
 #define AU1500_GPIO_202           50
@@ -373,14 +427,79 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
 #define AU1500_GPIO_207           62
 #define AU1500_GPIO_208_215       63
 
-#define AU1000_MAX_INTR           63
+#define UART0_ADDR                0xB1100000
+#define UART3_ADDR                0xB1400000
+
+#define USB_OHCI_BASE             0x10100000 // phys addr for ioremap
+#define USB_HOST_CONFIG           0xB017fffc
+
+#define AU1500_ETH0_BASE	  0xB1500000
+#define AU1500_ETH1_BASE	  0xB1510000
+#define AU1500_MAC0_ENABLE       0xB1520000
+#define AU1500_MAC1_ENABLE       0xB1520004
+#define NUM_ETH_INTERFACES 2
+#endif // CONFIG_SOC_AU1500
 
-#define AU1100_SD		2
+/* Au1100 */
+#ifdef CONFIG_SOC_AU1100
+#define AU1100_UART0_INT          0
+#define AU1100_UART1_INT          1
+#define AU1100_SD_INT             2
+#define AU1100_UART3_INT          3
+#define AU1000_SSI0_INT           4
+#define AU1000_SSI1_INT           5
+#define AU1000_DMA_INT_BASE       6
+#define AU1000_TOY_INT            14
+#define AU1000_TOY_MATCH0_INT     15
+#define AU1000_TOY_MATCH1_INT     16
+#define AU1000_TOY_MATCH2_INT     17
+#define AU1000_RTC_INT            18
+#define AU1000_RTC_MATCH0_INT     19
+#define AU1000_RTC_MATCH1_INT     20
+#define AU1000_RTC_MATCH2_INT     21
+#define AU1000_IRDA_TX_INT        22
+#define AU1000_IRDA_RX_INT        23
+#define AU1000_USB_DEV_REQ_INT    24
+#define AU1000_USB_DEV_SUS_INT    25
+#define AU1000_USB_HOST_INT       26
+#define AU1000_ACSYNC_INT         27
+#define AU1100_MAC0_DMA_INT       28
 #define	AU1100_GPIO_208_215	29
-// Seperate defines for AU1550 SOC
-#define AU1550_UART0_INT          AU1000_UART0_INT
-#define AU1550_PCI_INTA           AU1000_PCI_INTA
-#define AU1550_PCI_INTB           AU1000_PCI_INTB
+#define	AU1100_LCD_INT            30
+#define AU1000_AC97C_INT          31
+#define AU1000_GPIO_0             32
+#define AU1000_GPIO_1             33
+#define AU1000_GPIO_2             34
+#define AU1000_GPIO_3             35
+#define AU1000_GPIO_4             36
+#define AU1000_GPIO_5             37
+#define AU1000_GPIO_6             38
+#define AU1000_GPIO_7             39
+#define AU1000_GPIO_8             40
+#define AU1000_GPIO_9             41
+#define AU1000_GPIO_10            42
+#define AU1000_GPIO_11            43
+#define AU1000_GPIO_12            44
+#define AU1000_GPIO_13            45
+#define AU1000_GPIO_14            46
+#define AU1000_GPIO_15            47
+
+#define UART0_ADDR                0xB1100000
+#define UART1_ADDR                0xB1200000
+#define UART3_ADDR                0xB1400000
+
+#define USB_OHCI_BASE             0x10100000 // phys addr for ioremap
+#define USB_HOST_CONFIG           0xB017fffc
+
+#define AU1100_ETH0_BASE	  0xB0500000
+#define AU1100_MAC0_ENABLE       0xB0520000
+#define NUM_ETH_INTERFACES 1
+#endif // CONFIG_SOC_AU1100
+
+#ifdef CONFIG_SOC_AU1550
+#define AU1550_UART0_INT          0
+#define AU1550_PCI_INTA           1
+#define AU1550_PCI_INTB           2
 #define AU1550_DDMA_INT           3
 #define AU1550_CRYPTO_INT         4
 #define AU1550_PCI_INTC           5
@@ -404,11 +523,27 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
 #define AU1550_USB_DEV_REQ_INT    24
 #define AU1550_USB_DEV_SUS_INT    25
 #define AU1550_USB_HOST_INT       26
+#define AU1000_USB_DEV_REQ_INT    AU1550_USB_DEV_REQ_INT
+#define AU1000_USB_DEV_SUS_INT    AU1550_USB_DEV_SUS_INT
+#define AU1000_USB_HOST_INT       AU1550_USB_HOST_INT
 #define AU1550_MAC0_DMA_INT       27
 #define AU1550_MAC1_DMA_INT       28
-#define AU1550_ETH0_IRQ           AU1550_MAC0_DMA_INT
-#define AU1550_ETH1_IRQ           AU1550_MAC1_DMA_INT
-
+#define AU1000_GPIO_0             32
+#define AU1000_GPIO_1             33
+#define AU1000_GPIO_2             34
+#define AU1000_GPIO_3             35
+#define AU1000_GPIO_4             36
+#define AU1000_GPIO_5             37
+#define AU1000_GPIO_6             38
+#define AU1000_GPIO_7             39
+#define AU1000_GPIO_8             40
+#define AU1000_GPIO_9             41
+#define AU1000_GPIO_10            42
+#define AU1000_GPIO_11            43
+#define AU1000_GPIO_12            44
+#define AU1000_GPIO_13            45
+#define AU1000_GPIO_14            46
+#define AU1000_GPIO_15            47
 #define AU1550_GPIO_200           48
 #define AU1500_GPIO_201_205       49	// Logical or of GPIO201:205
 #define AU1500_GPIO_16            50
@@ -426,7 +561,101 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
 #define AU1500_GPIO_207           62
 #define AU1500_GPIO_208_218       63	// Logical or of GPIO208:218
 
-// REDEFINE SECONDARY GPIO BLOCK INTO IC1 CONTROLLER HERE
+#define UART0_ADDR                0xB1100000
+#define UART1_ADDR                0xB1200000
+#define UART3_ADDR                0xB1400000
+
+#define USB_OHCI_BASE             0x14020000 // phys addr for ioremap
+#define USB_HOST_CONFIG           0xB4027ffc
+
+#define AU1550_ETH0_BASE      0xB0500000
+#define AU1550_ETH1_BASE      0xB0510000
+#define AU1550_MAC0_ENABLE       0xB0520000
+#define AU1550_MAC1_ENABLE       0xB0520004
+#define NUM_ETH_INTERFACES 2
+#endif // CONFIG_SOC_AU1550
+
+#ifdef CONFIG_SOC_AU1200
+#define AU1200_UART0_INT          0
+#define AU1200_SWT_INT            1
+#define AU1200_SD_INT             2
+#define AU1200_DDMA_INT           3
+#define AU1200_MAE_BE_INT         4
+#define AU1200_GPIO_200           5
+#define AU1200_GPIO_201           6
+#define AU1200_GPIO_202           7
+#define AU1200_UART1_INT          8
+#define AU1200_MAE_FE_INT         9
+#define AU1200_PSC0_INT           10
+#define AU1200_PSC1_INT           11
+#define AU1200_AES_INT            12
+#define AU1200_CAMERA_INT         13
+#define AU1200_TOY_INT			  14
+#define AU1200_TOY_MATCH0_INT     15
+#define AU1200_TOY_MATCH1_INT     16
+#define AU1200_TOY_MATCH2_INT     17
+#define AU1200_RTC_INT            18
+#define AU1200_RTC_MATCH0_INT     19
+#define AU1200_RTC_MATCH1_INT     20
+#define AU1200_RTC_MATCH2_INT     21
+#define AU1200_NAND_INT           23
+#define AU1200_GPIO_204           24
+#define AU1200_GPIO_205           25
+#define AU1200_GPIO_206           26
+#define AU1200_GPIO_207           27
+#define AU1200_GPIO_208_215       28 // Logical OR of 208:215
+#define AU1200_USB_INT            29
+#define AU1200_LCD_INT            30
+#define AU1200_MAE_BOTH_INT       31
+#define AU1000_GPIO_0             32
+#define AU1000_GPIO_1             33
+#define AU1000_GPIO_2             34
+#define AU1000_GPIO_3             35
+#define AU1000_GPIO_4             36
+#define AU1000_GPIO_5             37
+#define AU1000_GPIO_6             38
+#define AU1000_GPIO_7             39
+#define AU1000_GPIO_8             40
+#define AU1000_GPIO_9             41
+#define AU1000_GPIO_10            42
+#define AU1000_GPIO_11            43
+#define AU1000_GPIO_12            44
+#define AU1000_GPIO_13            45
+#define AU1000_GPIO_14            46
+#define AU1000_GPIO_15            47
+#define AU1000_GPIO_16            48
+#define AU1000_GPIO_17            49
+#define AU1000_GPIO_18            50
+#define AU1000_GPIO_19            51
+#define AU1000_GPIO_20            52
+#define AU1000_GPIO_21            53
+#define AU1000_GPIO_22            54
+#define AU1000_GPIO_23            55
+#define AU1000_GPIO_24            56
+#define AU1000_GPIO_25            57
+#define AU1000_GPIO_26            58
+#define AU1000_GPIO_27            59
+#define AU1000_GPIO_28            60
+#define AU1000_GPIO_29            61
+#define AU1000_GPIO_30            62
+#define AU1000_GPIO_31            63
+
+#define UART0_ADDR                0xB1100000
+#define UART1_ADDR                0xB1200000
+
+#define USB_OHCI_BASE             0x14020000 // phys addr for ioremap
+#define USB_HOST_CONFIG           0xB4027ffc
+
+// these are here for prototyping on au1550 (do not exist on au1200)
+#define AU1200_ETH0_BASE      0xB0500000
+#define AU1200_ETH1_BASE      0xB0510000
+#define AU1200_MAC0_ENABLE       0xB0520000
+#define AU1200_MAC1_ENABLE       0xB0520004
+#define NUM_ETH_INTERFACES 2
+#endif // CONFIG_SOC_AU1200
+
+#define AU1000_LAST_INTC0_INT     31
+#define AU1000_MAX_INTR           63
 
 
 /* Programmable Counters 0 and 1 */
@@ -500,16 +729,7 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
   #define I2S_CONTROL_CE        (1<<0)
 
 /* USB Host Controller */
-// We pass USB_OHCI_BASE to ioremap, so it needs to be a physical address
-#if defined( CONFIG_SOC_AU1550 )
-#define USB_OHCI_BASE             0x14020000
-#define USB_OHCI_LEN              0x00100000
-#define USB_HOST_CONFIG           0xB4027ffc
-#else
-#define USB_OHCI_BASE             0x10100000
 #define USB_OHCI_LEN              0x00100000
-#define USB_HOST_CONFIG           0xB017fffc
-#endif
 
 /* USB Device Controller */
 #define USBD_EP0RD                0xB0200000
@@ -554,13 +774,6 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
   #define USBDEV_CE     (1<<0)
 
 /* Ethernet Controllers  */
-#define AU1000_ETH0_BASE          0xB0500000
-#define AU1000_ETH1_BASE          0xB0510000
-#define AU1500_ETH0_BASE	  0xB1500000
-#define AU1500_ETH1_BASE	  0xB1510000
-#define AU1100_ETH0_BASE	  0xB0500000
-#define AU1550_ETH0_BASE      0xB0500000
-#define AU1550_ETH1_BASE      0xB0510000
 
 /* 4 byte offsets from AU1000_ETH_BASE */
 #define MAC_CONTROL                     0x0
@@ -605,11 +818,6 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
 #define MAC_VLAN2_TAG                  0x24
 
 /* Ethernet Controller Enable */
-#define AU1000_MAC0_ENABLE       0xB0520000
-#define AU1000_MAC1_ENABLE       0xB0520004
-#define AU1500_MAC0_ENABLE       0xB1520000
-#define AU1500_MAC1_ENABLE       0xB1520004
-#define AU1100_MAC0_ENABLE       0xB0520000
 
   #define MAC_EN_CLOCK_ENABLE         (1<<0)
   #define MAC_EN_RESET0               (1<<1)
@@ -693,10 +901,6 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
 
 
 /* UARTS 0-3 */
-#define UART0_ADDR                0xB1100000
-#define UART1_ADDR                0xB1200000
-#define UART2_ADDR                0xB1300000
-#define UART3_ADDR                0xB1400000
 #define UART_BASE                 UART0_ADDR
 #define UART_DEBUG_BASE           UART3_ADDR
 
@@ -951,6 +1155,22 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
   #define SYS_PF_CS			(1<<16)	/* EXTCLK0/32khz to gpio2 */
   #define SYS_PF_EX0			(1<<9)	/* gpio2/clock */
 
+/* Au1550 Only.  Redefines lots of pins */
+  #define SYS_PF_PSC2_MASK		(7 << 17)
+  #define SYS_PF_PSC2_AC97		(0)
+  #define SYS_PF_PSC2_SPI		(0)
+  #define SYS_PF_PSC2_I2S		(1 << 17)
+  #define SYS_PF_PSC2_SMBUS		(3 << 17)
+  #define SYS_PF_PSC2_GPIO		(7 << 17)
+  #define SYS_PF_PSC3_MASK		(7 << 20)
+  #define SYS_PF_PSC3_AC97		(0)
+  #define SYS_PF_PSC3_SPI		(0)
+  #define SYS_PF_PSC3_I2S		(1 << 20)
+  #define SYS_PF_PSC3_SMBUS		(3 << 20)
+  #define SYS_PF_PSC3_GPIO		(7 << 20)
+  #define SYS_PF_PSC1_S1		(1 << 1)
+  #define SYS_PF_MUST_BE_SET		((1 << 5) | (1 << 2))
+
 #define SYS_TRIOUTRD              0xB1900100
 #define SYS_TRIOUTCLR             0xB1900100
 #define SYS_OUTPUTRD              0xB1900108
@@ -959,7 +1179,7 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
 #define SYS_PINSTATERD            0xB1900110
 #define SYS_PININPUTEN            0xB1900110
 
-/* GPIO2, Au1500 only */
+/* GPIO2, Au1500, Au1550 only */
 #define GPIO2_BASE                0xB1700000
 #define GPIO2_DIR                 (GPIO2_BASE + 0)
 #define GPIO2_OUTPUT              (GPIO2_BASE + 8)
@@ -1071,6 +1291,14 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
   #define AC97C_RS              (1<<1)
   #define AC97C_CE              (1<<0)
 
+ 
+/* Secure Digital (SD) Controller */
+#define SD0_XMIT_FIFO	0xB0600000
+#define SD0_RECV_FIFO	0xB0600004
+#define SD1_XMIT_FIFO	0xB0680000
+#define SD1_RECV_FIFO	0xB0680004
+
+
 #if defined (CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550)
 /* Au1500 PCI Controller */
 #define Au1500_CFG_BASE           0xB4005000 // virtual, kseg0 addr
@@ -1119,6 +1347,20 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
 #define IOMEM_RESOURCE_START  0x10000000
 #define IOMEM_RESOURCE_END    0xffffffff
 
+  /*
+   * Borrowed from the PPC arch:
+   * The following macro is used to lookup irqs in a standard table
+   * format for those PPC systems that do not already have PCI
+   * interrupts properly routed.
+   */
+  /* FIXME - double check this from asm-ppc/pci-bridge.h */
+#define PCI_IRQ_TABLE_LOOKUP                            \
+  ({ long _ctl_ = -1;                                 \
+      if (idsel >= min_idsel && idsel <= max_idsel && pin <= irqs_per_slot)    \
+	       _ctl_ = pci_irq_table[idsel - min_idsel][pin-1];               \
+		      _ctl_; })
+
+
 #else /* Au1000 and Au1100 */
 
 /* don't allow any legacy ports probing */
@@ -1146,10 +1388,19 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]
 
 #endif
 
-#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550)
-#define NUM_ETH_INTERFACES 2
-#elif defined(CONFIG_SOC_AU1100)
-#define NUM_ETH_INTERFACES 1
-#endif
+/* Processor information base on prid.
+ * Copied from PowerPC.
+ */
+struct cpu_spec {
+	/* CPU is matched via (PRID & prid_mask) == prid_value */
+	unsigned int	prid_mask;
+	unsigned int	prid_value;
+
+	char		*cpu_name;
+	unsigned char	cpu_od;		/* Set Config[OD] */
+	unsigned char	cpu_bclk;	/* Enable BCLK switching */
+};
 
+extern struct cpu_spec		cpu_specs[];
+extern struct cpu_spec		*cur_cpu_spec[];
 #endif
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/au1000_dma.h linux-2.4.29-pre3/include/asm-mips/au1000_dma.h
--- linux-2.4.28/include/asm-mips/au1000_dma.h	2003-08-25 11:44:43.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/au1000_dma.h	2004-12-22 16:07:32.422247624 +0000
@@ -51,6 +51,7 @@
 #define DMA_DAH_MASK		(0x0f << 20)
 #define DMA_DID_BIT		16
 #define DMA_DID_MASK		(0x0f << DMA_DID_BIT)
+#define DMA_DS			(1<<15)
 #define DMA_BE			(1<<13)
 #define DMA_DR			(1<<12)
 #define DMA_TS8			(1<<11)
@@ -100,6 +101,15 @@ enum {
 	DMA_NUM_DEV
 };
 
+/* DMA Device ID's for 2nd bank (AU1100) follow */
+enum {
+	DMA_ID_SD0_TX = 0,
+	DMA_ID_SD0_RX,
+	DMA_ID_SD1_TX,
+	DMA_ID_SD1_RX,
+	DMA_NUM_DEV_BANK2
+};
+
 struct dma_chan {
 	int dev_id;		// this channel is allocated if >=0, free otherwise
 	unsigned int io;
@@ -127,7 +137,7 @@ extern spinlock_t au1000_dma_spin_lock;
 
 static __inline__ struct dma_chan *get_dma_chan(unsigned int dmanr)
 {
-	if (dmanr > NUM_AU1000_DMA_CHANNELS
+	if (dmanr >= NUM_AU1000_DMA_CHANNELS
 	    || au1000_dma_table[dmanr].dev_id < 0)
 		return NULL;
 	return &au1000_dma_table[dmanr];
@@ -206,8 +216,8 @@ static __inline__ void disable_dma(unsig
 
 	halt_dma(dmanr);
 
-		// now we can disable the buffers
-		au_writel(~DMA_GO, chan->io + DMA_MODE_CLEAR);
+	// now we can disable the buffers
+	au_writel(~DMA_GO, chan->io + DMA_MODE_CLEAR);
 }
 
 static __inline__ int dma_halted(unsigned int dmanr)
@@ -287,6 +297,9 @@ static __inline__ void set_dma_fifo_addr
 	if (!chan)
 		return;
 
+	if (chan->mode & DMA_DS)	/* second bank of device ids */
+		return;
+
 	if (chan->dev_id != DMA_ID_GP04 && chan->dev_id != DMA_ID_GP05)
 		return;
 
@@ -431,3 +444,4 @@ static __inline__ int get_dma_residue(un
 }
 
 #endif /* __ASM_AU1000_DMA_H */
+
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/au1000_pcmcia.h linux-2.4.29-pre3/include/asm-mips/au1000_pcmcia.h
--- linux-2.4.28/include/asm-mips/au1000_pcmcia.h	2003-08-25 11:44:43.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/au1000_pcmcia.h	2004-12-22 16:07:37.830425456 +0000
@@ -44,7 +44,7 @@
 #define AU1X_SOCK1_IO        0xF08000000
 #define AU1X_SOCK1_PHYS_ATTR 0xF48000000
 #define AU1X_SOCK1_PHYS_MEM  0xF88000000
-#elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500)
+#elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_PB1550) || defined(CONFIG_MIPS_DB1550)
 #define AU1X_SOCK1_IO        0xF04000000
 #define AU1X_SOCK1_PHYS_ATTR 0xF44000000
 #define AU1X_SOCK1_PHYS_MEM  0xF84000000
@@ -100,14 +100,5 @@ struct pcmcia_low_level {
 	int (*configure_socket)(const struct pcmcia_configure *);
 };
 
-#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_PB1500)
-extern struct pcmcia_low_level pb1x00_pcmcia_ops;
-#elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500)
-extern struct pcmcia_low_level db1x00_pcmcia_ops;
-#elif defined(CONFIG_MIPS_XXS1500)
-extern struct pcmcia_low_level xxs1500_pcmcia_ops;
-#else
-error unknown Au1000 board
-#endif
-
+extern struct pcmcia_low_level au1x00_pcmcia_ops;
 #endif /* __ASM_AU1000_PCMCIA_H */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/au1100_mmc.h linux-2.4.29-pre3/include/asm-mips/au1100_mmc.h
--- linux-2.4.28/include/asm-mips/au1100_mmc.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/au1100_mmc.h	2004-12-22 16:05:31.000000000 +0000
@@ -0,0 +1,205 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ *	Defines for using the MMC/SD controllers on the
+ *      Alchemy Au1100 mips processor.
+ *
+ * Copyright (c) 2003 Embedded Edge, LLC.
+ * Author: Embedded Edge, LLC.
+ *         	dan@embeddededge.com or tim@embeddededge.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+/*
+ * AU1100 MMC/SD definitions.
+ *
+ * From "AMD Alchemy Solutions Au1100 Processor Data Book - Preliminary"
+ *    June, 2003
+ */
+
+#ifndef __ASM_AU1100_MMC_H
+#define __ASM_AU1100_MMC_H
+
+
+#define NUM_AU1100_MMC_CONTROLLERS	2
+
+
+#define AU1100_SD_IRQ	2
+
+
+#define SD0_BASE	0xB0600000
+#define SD1_BASE	0xB0680000
+
+
+/*
+ *  Register offsets.
+ */
+#define SD_TXPORT	(0x0000)
+#define SD_RXPORT	(0x0004)
+#define SD_CONFIG	(0x0008)
+#define SD_ENABLE	(0x000C)
+#define SD_CONFIG2	(0x0010)
+#define SD_BLKSIZE	(0x0014)
+#define SD_STATUS	(0x0018)
+#define SD_DEBUG	(0x001C)
+#define SD_CMD		(0x0020)
+#define SD_CMDARG	(0x0024)
+#define SD_RESP3	(0x0028)
+#define SD_RESP2	(0x002C)
+#define SD_RESP1	(0x0030)
+#define SD_RESP0	(0x0034)
+#define SD_TIMEOUT	(0x0038)
+
+
+/*
+ *  SD_TXPORT bit definitions.
+ */
+#define SD_TXPORT_TXD	(0x000000ff)
+
+
+/*
+ *  SD_RXPORT bit definitions.
+ */
+#define SD_RXPORT_RXD	(0x000000ff)
+
+
+/*
+ *  SD_CONFIG bit definitions.
+ */
+#define SD_CONFIG_DIV	(0x000001ff)
+#define SD_CONFIG_DE	(0x00000200)
+#define SD_CONFIG_NE	(0x00000400)
+#define SD_CONFIG_TU	(0x00000800)
+#define SD_CONFIG_TO	(0x00001000)
+#define SD_CONFIG_RU	(0x00002000)
+#define SD_CONFIG_RO	(0x00004000)
+#define SD_CONFIG_I	(0x00008000)
+#define SD_CONFIG_CR	(0x00010000)
+#define SD_CONFIG_RAT	(0x00020000)
+#define SD_CONFIG_DD	(0x00040000)
+#define SD_CONFIG_DT	(0x00080000)
+#define SD_CONFIG_SC	(0x00100000)
+#define SD_CONFIG_RC	(0x00200000)
+#define SD_CONFIG_WC	(0x00400000)
+#define SD_CONFIG_xxx	(0x00800000)
+#define SD_CONFIG_TH	(0x01000000)
+#define SD_CONFIG_TE	(0x02000000)
+#define SD_CONFIG_TA	(0x04000000)
+#define SD_CONFIG_RH	(0x08000000)
+#define SD_CONFIG_RA	(0x10000000)
+#define SD_CONFIG_RF	(0x20000000)
+#define SD_CONFIG_CD	(0x40000000)
+#define SD_CONFIG_SI	(0x80000000)
+
+
+/*
+ *  SD_ENABLE bit definitions.
+ */
+#define SD_ENABLE_CE	(0x00000001)
+#define SD_ENABLE_R	(0x00000002)
+
+
+/*
+ *  SD_CONFIG2 bit definitions.
+ */
+#define SD_CONFIG2_EN	(0x00000001)
+#define SD_CONFIG2_FF	(0x00000002)
+#define SD_CONFIG2_xx1	(0x00000004)
+#define SD_CONFIG2_DF	(0x00000008)
+#define SD_CONFIG2_DC	(0x00000010)
+#define SD_CONFIG2_xx2	(0x000000e0)
+#define SD_CONFIG2_WB	(0x00000100)
+#define SD_CONFIG2_RW	(0x00000200)
+
+
+/*
+ *  SD_BLKSIZE bit definitions.
+ */
+#define SD_BLKSIZE_BS	(0x000007ff)
+#define SD_BLKSIZE_BS_SHIFT	 (0)
+#define SD_BLKSIZE_BC	(0x01ff0000)
+#define SD_BLKSIZE_BC_SHIFT	(16)
+
+
+/*
+ *  SD_STATUS bit definitions.
+ */
+#define SD_STATUS_DCRCW	(0x00000007)
+#define SD_STATUS_xx1	(0x00000008)
+#define SD_STATUS_CB	(0x00000010)
+#define SD_STATUS_DB	(0x00000020)
+#define SD_STATUS_CF	(0x00000040)
+#define SD_STATUS_D3	(0x00000080)
+#define SD_STATUS_xx2	(0x00000300)
+#define SD_STATUS_NE	(0x00000400)
+#define SD_STATUS_TU	(0x00000800)
+#define SD_STATUS_TO	(0x00001000)
+#define SD_STATUS_RU	(0x00002000)
+#define SD_STATUS_RO	(0x00004000)
+#define SD_STATUS_I	(0x00008000)
+#define SD_STATUS_CR	(0x00010000)
+#define SD_STATUS_RAT	(0x00020000)
+#define SD_STATUS_DD	(0x00040000)
+#define SD_STATUS_DT	(0x00080000)
+#define SD_STATUS_SC	(0x00100000)
+#define SD_STATUS_RC	(0x00200000)
+#define SD_STATUS_WC	(0x00400000)
+#define SD_STATUS_xx3	(0x00800000)
+#define SD_STATUS_TH	(0x01000000)
+#define SD_STATUS_TE	(0x02000000)
+#define SD_STATUS_TA	(0x04000000)
+#define SD_STATUS_RH	(0x08000000)
+#define SD_STATUS_RA	(0x10000000)
+#define SD_STATUS_RF	(0x20000000)
+#define SD_STATUS_CD	(0x40000000)
+#define SD_STATUS_SI	(0x80000000)
+
+
+/*
+ *  SD_CMD bit definitions.
+ */
+#define SD_CMD_GO	(0x00000001)
+#define SD_CMD_RY	(0x00000002)
+#define SD_CMD_xx1	(0x0000000c)
+#define SD_CMD_CT_MASK	(0x000000f0)
+#define SD_CMD_CT_0	(0x00000000)
+#define SD_CMD_CT_1	(0x00000010)
+#define SD_CMD_CT_2	(0x00000020)
+#define SD_CMD_CT_3	(0x00000030)
+#define SD_CMD_CT_4	(0x00000040)
+#define SD_CMD_CT_5	(0x00000050)
+#define SD_CMD_CT_6	(0x00000060)
+#define SD_CMD_CT_7	(0x00000070)
+#define SD_CMD_CI	(0x0000ff00)
+#define SD_CMD_CI_SHIFT		(8)
+#define SD_CMD_RT_MASK	(0x00ff0000)
+#define SD_CMD_RT_0	(0x00000000)
+#define SD_CMD_RT_1	(0x00010000)
+#define SD_CMD_RT_2	(0x00020000)
+#define SD_CMD_RT_3	(0x00030000)
+#define SD_CMD_RT_4	(0x00040000)
+#define SD_CMD_RT_5	(0x00050000)
+#define SD_CMD_RT_6	(0x00060000)
+#define SD_CMD_RT_1B	(0x00810000)
+
+
+#endif /* __ASM_AU1100_MMC_H */
+
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/au1550_spi.h linux-2.4.29-pre3/include/asm-mips/au1550_spi.h
--- linux-2.4.28/include/asm-mips/au1550_spi.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/au1550_spi.h	2004-12-22 16:05:44.527650096 +0000
@@ -0,0 +1,38 @@
+/*
+ *	API to Alchemy Au1550 SPI device.
+ *
+ * Copyright 2004 Embedded Edge, LLC.
+ *	dan@embeddededge.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __AU1550_SPI_H
+#define __AU1550_SPI_H
+
+#include <linux/ioctl.h>
+
+#define AU1550SPI_IOC_MAGIC 'S'
+
+#define AU1550SPI_SET_BAUD	_IOW(AU1550SPI_IOC_MAGIC, 0, int *)
+#define AU1550SPI_WORD_LEN	_IOW(AU1550SPI_IOC_MAGIC, 1, int)
+
+#endif /* __AU1000_SPI_H */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/au1xxx_dbdma.h linux-2.4.29-pre3/include/asm-mips/au1xxx_dbdma.h
--- linux-2.4.28/include/asm-mips/au1xxx_dbdma.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/au1xxx_dbdma.h	2004-12-22 16:06:31.055576776 +0000
@@ -0,0 +1,318 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Include file for Alchemy Semiconductor's Au1550 Descriptor
+ *	Based DMA Controller.
+ *
+ * Copyright 2004 Embedded Edge, LLC
+ *	dan@embeddededge.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Specifics for the Au1xxx Descriptor-Based DMA Controllers, first
+ * seen in the AU1550 part.
+ */
+#ifndef _AU1000_DBDMA_H_
+#define _AU1000_DBDMA_H_
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+/* The DMA base addresses.
+ * The Channels are every 256 bytes (0x0100) from the channel 0 base.
+ * Interrupt status/enable is bits 15:0 for channels 15 to zero.
+ */
+#define DDMA_GLOBAL_BASE	0xb4003000
+#define DDMA_CHANNEL_BASE	0xb4002000
+
+typedef struct dbdma_global {
+	u32	ddma_config;
+	u32	ddma_intstat;
+	u32	ddma_throttle;
+	u32	ddma_inten;
+} dbdma_global_t;
+
+/* General Configuration.
+*/
+#define DDMA_CONFIG_AF		(1 << 2)
+#define DDMA_CONFIG_AH		(1 << 1)
+#define DDMA_CONFIG_AL		(1 << 0)
+
+#define DDMA_THROTTLE_EN	(1 << 31)
+
+/* The structure of a DMA Channel.
+*/
+typedef struct au1xxx_dma_channel {
+	u32	ddma_cfg;	/* See below */
+	u32	ddma_desptr;	/* 32-byte aligned pointer to descriptor */
+	u32	ddma_statptr;	/* word aligned pointer to status word */
+	u32	ddma_dbell;	/* A write activates channel operation */
+	u32	ddma_irq;	/* If bit 0 set, interrupt pending */
+	u32	ddma_stat;	/* See below */
+	u32	ddma_bytecnt;	/* Byte count, valid only when chan idle */
+	/* Remainder, up to the 256 byte boundary, is reserved.
+	*/
+} au1x_dma_chan_t;
+
+#define DDMA_CFG_SED	(1 << 9)	/* source DMA level/edge detect */
+#define DDMA_CFG_SP	(1 << 8)	/* source DMA polarity */
+#define DDMA_CFG_DED	(1 << 7)	/* destination DMA level/edge detect */
+#define DDMA_CFG_DP	(1 << 6)	/* destination DMA polarity */
+#define DDMA_CFG_SYNC	(1 << 5)	/* Sync static bus controller */
+#define DDMA_CFG_PPR	(1 << 4)	/* PCI posted read/write control */
+#define DDMA_CFG_DFN	(1 << 3)	/* Descriptor fetch non-coherent */
+#define DDMA_CFG_SBE	(1 << 2)	/* Source big endian */
+#define DDMA_CFG_DBE	(1 << 1)	/* Destination big endian */
+#define DDMA_CFG_EN	(1 << 0)	/* Channel enable */
+
+/* Always set when descriptor processing done, regardless of
+ * interrupt enable state.  Reflected in global intstat, don't
+ * clear this until global intstat is read/used.
+ */
+#define DDMA_IRQ_IN	(1 << 0)
+
+#define DDMA_STAT_DB	(1 << 2)	/* Doorbell pushed */
+#define DDMA_STAT_V	(1 << 1)	/* Descriptor valid */
+#define DDMA_STAT_H	(1 << 0)	/* Channel Halted */
+
+/* "Standard" DDMA Descriptor.
+ * Must be 32-byte aligned.
+ */
+typedef struct au1xxx_ddma_desc {
+	u32	dscr_cmd0;		/* See below */
+	u32	dscr_cmd1;		/* See below */
+	u32	dscr_source0;		/* source phys address */
+	u32	dscr_source1;		/* See below */
+	u32	dscr_dest0;		/* Destination address */
+	u32	dscr_dest1;		/* See below */
+	u32	dscr_stat;		/* completion status */
+	u32	dscr_nxtptr;		/* Next descriptor pointer (mostly) */
+} au1x_ddma_desc_t;
+
+#define DSCR_CMD0_V		(1 << 31)	/* Descriptor valid */
+#define DSCR_CMD0_MEM		(1 << 30)	/* mem-mem transfer */
+#define DSCR_CMD0_SID_MASK	(0x1f << 25)	/* Source ID */
+#define DSCR_CMD0_DID_MASK	(0x1f << 20)	/* Destination ID */
+#define DSCR_CMD0_SW_MASK	(0x3 << 18)	/* Source Width */
+#define DSCR_CMD0_DW_MASK	(0x3 << 16)	/* Destination Width */
+#define DSCR_CMD0_ARB		(0x1 << 15)	/* Set for Hi Pri */
+#define DSCR_CMD0_DT_MASK	(0x3 << 13)	/* Descriptor Type */
+#define DSCR_CMD0_SN		(0x1 << 12)	/* Source non-coherent */
+#define DSCR_CMD0_DN		(0x1 << 11)	/* Destination non-coherent */
+#define DSCR_CMD0_SM		(0x1 << 10)	/* Stride mode */
+#define DSCR_CMD0_IE		(0x1 << 8)	/* Interrupt Enable */
+#define DSCR_CMD0_SP		(0x1 << 4)	/* Status pointer select */
+#define DSCR_CMD0_CV		(0x1 << 2)	/* Clear Valid when done */
+#define DSCR_CMD0_ST_MASK	(0x3 << 0)	/* Status instruction */
+
+/* Command 0 device IDs.
+*/
+#ifdef CONFIG_SOC_AU1550
+#define DSCR_CMD0_UART0_TX	0
+#define DSCR_CMD0_UART0_RX	1
+#define DSCR_CMD0_UART3_TX	2
+#define DSCR_CMD0_UART3_RX	3
+#define DSCR_CMD0_DMA_REQ0	4
+#define DSCR_CMD0_DMA_REQ1	5
+#define DSCR_CMD0_DMA_REQ2	6
+#define DSCR_CMD0_DMA_REQ3	7
+#define DSCR_CMD0_USBDEV_RX0	8
+#define DSCR_CMD0_USBDEV_TX0	9
+#define DSCR_CMD0_USBDEV_TX1	10
+#define DSCR_CMD0_USBDEV_TX2	11
+#define DSCR_CMD0_USBDEV_RX3	12
+#define DSCR_CMD0_USBDEV_RX4	13
+#define DSCR_CMD0_PSC0_TX	14
+#define DSCR_CMD0_PSC0_RX	15
+#define DSCR_CMD0_PSC1_TX	16
+#define DSCR_CMD0_PSC1_RX	17
+#define DSCR_CMD0_PSC2_TX	18
+#define DSCR_CMD0_PSC2_RX	19
+#define DSCR_CMD0_PSC3_TX	20
+#define DSCR_CMD0_PSC3_RX	21
+#define DSCR_CMD0_PCI_WRITE	22
+#define DSCR_CMD0_NAND_FLASH	23
+#define DSCR_CMD0_MAC0_RX	24
+#define DSCR_CMD0_MAC0_TX	25
+#define DSCR_CMD0_MAC1_RX	26
+#define DSCR_CMD0_MAC1_TX	27
+#endif /* CONFIG_SOC_AU1550 */
+
+#ifdef CONFIG_SOC_AU1200
+#define DSCR_CMD0_UART0_TX	0
+#define DSCR_CMD0_UART0_RX	1
+#define DSCR_CMD0_UART1_TX	2
+#define DSCR_CMD0_UART1_RX	3
+#define DSCR_CMD0_DMA_REQ0	4
+#define DSCR_CMD0_DMA_REQ1	5
+#define DSCR_CMD0_MAE_BE	6
+#define DSCR_CMD0_MAE_FE	7
+#define DSCR_CMD0_SDMS_TX0	8
+#define DSCR_CMD0_SDMS_RX0	9
+#define DSCR_CMD0_SDMS_TX1	10
+#define DSCR_CMD0_SDMS_RX1	11
+#define DSCR_CMD0_AES_TX	12
+#define DSCR_CMD0_AES_RX	13
+#define DSCR_CMD0_PSC0_TX	14
+#define DSCR_CMD0_PSC0_RX	15
+#define DSCR_CMD0_PSC1_TX	16
+#define DSCR_CMD0_PSC1_RX	17
+#define DSCR_CMD0_CIM_RXA	18
+#define DSCR_CMD0_CIM_RXB	19
+#define DSCR_CMD0_CIM_RXC	20
+#define DSCR_CMD0_MAE_BOTH	21
+#define DSCR_CMD0_LCD		22
+#define DSCR_CMD0_NAND_FLASH	23
+#define DSCR_CMD0_PSC0_SYNC	24
+#define DSCR_CMD0_PSC1_SYNC	25
+#define DSCR_CMD0_CIM_SYNC	26
+#endif /* CONFIG_SOC_AU1200 */
+
+#define DSCR_CMD0_THROTTLE	30
+#define DSCR_CMD0_ALWAYS	31
+#define DSCR_NDEV_IDS		32
+
+#define DSCR_CMD0_SID(x)	(((x) & 0x1f) << 25)
+#define DSCR_CMD0_DID(x)	(((x) & 0x1f) << 20)
+
+/* Source/Destination transfer width.
+*/
+#define DSCR_CMD0_BYTE		0
+#define DSCR_CMD0_HALFWORD	1
+#define DSCR_CMD0_WORD		2
+
+#define DSCR_CMD0_SW(x)		(((x) & 0x3) << 18)
+#define DSCR_CMD0_DW(x)		(((x) & 0x3) << 16)
+
+/* DDMA Descriptor Type.
+*/
+#define DSCR_CMD0_STANDARD	0
+#define DSCR_CMD0_LITERAL	1
+#define DSCR_CMD0_CMP_BRANCH	2
+
+#define DSCR_CMD0_DT(x)		(((x) & 0x3) << 13)
+
+/* Status Instruction.
+*/
+#define DSCR_CMD0_ST_NOCHANGE	0	/* Don't change */
+#define DSCR_CMD0_ST_CURRENT	1	/* Write current status */
+#define DSCR_CMD0_ST_CMD0	2	/* Write cmd0 with V cleared */
+#define DSCR_CMD0_ST_BYTECNT	3	/* Write remaining byte count */
+
+#define DSCR_CMD0_ST(x)		(((x) & 0x3) << 0)
+
+/* Descriptor Command 1
+*/
+#define DSCR_CMD1_SUPTR_MASK	(0xf << 28)	/* upper 4 bits of src addr */
+#define DSCR_CMD1_DUPTR_MASK	(0xf << 24)	/* upper 4 bits of dest addr */
+#define DSCR_CMD1_FL_MASK	(0x3 << 22)	/* Flag bits */
+#define DSCR_CMD1_BC_MASK	(0x3fffff)	/* Byte count */
+
+/* Flag description.
+*/
+#define DSCR_CMD1_FL_MEM_STRIDE0	0
+#define DSCR_CMD1_FL_MEM_STRIDE1	1
+#define DSCR_CMD1_FL_MEM_STRIDE2	2
+
+#define DSCR_CMD1_FL(x)		(((x) & 0x3) << 22)
+
+/* Source1, 1-dimensional stride.
+*/
+#define DSCR_SRC1_STS_MASK	(3 << 30)	/* Src xfer size */
+#define DSCR_SRC1_SAM_MASK	(3 << 28)	/* Src xfer movement */
+#define DSCR_SRC1_SB_MASK	(0x3fff << 14)	/* Block size */
+#define DSCR_SRC1_SB(x)		(((x) & 0x3fff) << 14)
+#define DSCR_SRC1_SS_MASK	(0x3fff << 0)	/* Stride */
+#define DSCR_SRC1_SS(x)		(((x) & 0x3fff) << 0)
+
+/* Dest1, 1-dimensional stride.
+*/
+#define DSCR_DEST1_DTS_MASK	(3 << 30)	/* Dest xfer size */
+#define DSCR_DEST1_DAM_MASK	(3 << 28)	/* Dest xfer movement */
+#define DSCR_DEST1_DB_MASK	(0x3fff << 14)	/* Block size */
+#define DSCR_DEST1_DB(x)	(((x) & 0x3fff) << 14)
+#define DSCR_DEST1_DS_MASK	(0x3fff << 0)	/* Stride */
+#define DSCR_DEST1_DS(x)	(((x) & 0x3fff) << 0)
+
+#define DSCR_xTS_SIZE1		0
+#define DSCR_xTS_SIZE2		1
+#define DSCR_xTS_SIZE4		2
+#define DSCR_xTS_SIZE8		3
+#define DSCR_SRC1_STS(x)	(((x) & 3) << 30)
+#define DSCR_DEST1_DTS(x)	(((x) & 3) << 30)
+
+#define DSCR_xAM_INCREMENT	0
+#define DSCR_xAM_DECREMENT	1
+#define DSCR_xAM_STATIC		2
+#define DSCR_xAM_BURST		3
+#define DSCR_SRC1_SAM(x)	(((x) & 3) << 28)
+#define DSCR_DEST1_DAM(x)	(((x) & 3) << 28)
+
+/* The next descriptor pointer.
+*/
+#define DSCR_NXTPTR_MASK	(0x07ffffff)
+#define DSCR_NXTPTR(x)		((x) >> 5)
+#define DSCR_GET_NXTPTR(x)	((x) << 5)
+#define DSCR_NXTPTR_MS		(1 << 27)
+
+/* The number of DBDMA channels.
+*/
+#define NUM_DBDMA_CHANS	16
+
+/* External functions for drivers to use.
+*/
+/* Use this to allocate a dbdma channel.  The device ids are one of the
+ * DSCR_CMD0 devices IDs, which is usually redefined to a more
+ * meaningful name.  The 'callback' is called during dma completion
+ * interrupt.
+ */
+u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
+       void (*callback)(int, void *, struct pt_regs *), void *callparam);
+
+#define DBDMA_MEM_CHAN	DSCR_CMD0_ALWAYS
+
+/* Set the device width of a in/out fifo.
+*/
+u32 au1xxx_dbdma_set_devwidth(u32 chanid, int bits);
+
+/* Allocate a ring of descriptors for dbdma.
+*/
+u32 au1xxx_dbdma_ring_alloc(u32 chanid, int entries);
+
+/* Put buffers on source/destination descriptors.
+*/
+u32 au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes);
+u32 au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes);
+
+/* Get a buffer from the destination descriptor.
+*/
+u32 au1xxx_dbdma_get_dest(u32 chanid, void **buf, int *nbytes);
+
+void au1xxx_dbdma_stop(u32 chanid);
+void au1xxx_dbdma_start(u32 chanid);
+void au1xxx_dbdma_reset(u32 chanid);
+u32 au1xxx_get_dma_residue(u32 chanid);
+
+void au1xxx_dbdma_chan_free(u32 chanid);
+void au1xxx_dbdma_dump(u32 chanid);
+
+#endif /* _LANGUAGE_ASSEMBLY */
+#endif /* _AU1000_DBDMA_H_ */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/au1xxx_psc.h linux-2.4.29-pre3/include/asm-mips/au1xxx_psc.h
--- linux-2.4.28/include/asm-mips/au1xxx_psc.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/au1xxx_psc.h	2004-12-22 16:05:42.578946344 +0000
@@ -0,0 +1,522 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ *	Include file for Alchemy Semiconductor's Au1k CPU.
+ *
+ * Copyright 2004 Embedded Edge, LLC
+ *	dan@embeddededge.com
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Specifics for the Au1xxx Programmable Serial Controllers, first
+ * seen in the AU1550 part.
+ */
+#ifndef _AU1000_PSC_H_
+#define _AU1000_PSC_H_
+
+/* The PSC base addresses.  */
+#ifdef CONFIG_SOC_AU1550
+#define PSC0_BASE_ADDR		0xb1a00000
+#define PSC1_BASE_ADDR		0xb1b00000
+#define PSC2_BASE_ADDR		0xb0a00000
+#define PSC3_BASE_ADDR		0xb0d00000
+#endif
+
+/* The PSC select and control registers are common to
+ * all protocols.
+ */
+#define PSC_SEL_OFFSET		0x00000000
+#define PSC_CTRL_OFFSET		0x00000004
+
+#define PSC_SEL_CLK_MASK	(3 << 4)
+#define PSC_SEL_CLK_INTCLK	(0 << 4)
+#define PSC_SEL_CLK_EXTCLK	(1 << 4)
+#define PSC_SEL_CLK_SERCLK	(2 << 4)
+
+#define PSC_SEL_PS_MASK		0x00000007
+#define PSC_SEL_PS_DISABLED	(0)
+#define PSC_SEL_PS_SPIMODE	(2)
+#define PSC_SEL_PS_I2SMODE	(3)
+#define PSC_SEL_PS_AC97MODE	(4)
+#define PSC_SEL_PS_SMBUSMODE	(5)
+
+#define PSC_CTRL_DISABLE	(0)
+#define PSC_CTRL_SUSPEND	(2)
+#define PSC_CTRL_ENABLE		(3)
+
+/* AC97 Registers.
+*/
+#define PSC_AC97CFG_OFFSET	0x00000008
+#define PSC_AC97MSK_OFFSET	0x0000000c
+#define PSC_AC97PCR_OFFSET	0x00000010
+#define PSC_AC97STAT_OFFSET	0x00000014
+#define PSC_AC97EVNT_OFFSET	0x00000018
+#define PSC_AC97TXRX_OFFSET	0x0000001c
+#define PSC_AC97CDC_OFFSET	0x00000020
+#define PSC_AC97RST_OFFSET	0x00000024
+#define PSC_AC97GPO_OFFSET	0x00000028
+#define PSC_AC97GPI_OFFSET	0x0000002c
+
+#define AC97_PSC_SEL		(AC97_PSC_BASE + PSC_SEL_OFFSET)
+#define AC97_PSC_CTRL		(AC97_PSC_BASE + PSC_CTRL_OFFSET)
+#define PSC_AC97CFG		(AC97_PSC_BASE + PSC_AC97CFG_OFFSET)
+#define PSC_AC97MSK		(AC97_PSC_BASE + PSC_AC97MSK_OFFSET)
+#define PSC_AC97PCR		(AC97_PSC_BASE + PSC_AC97PCR_OFFSET)
+#define PSC_AC97STAT		(AC97_PSC_BASE + PSC_AC97STAT_OFFSET)
+#define PSC_AC97EVNT		(AC97_PSC_BASE + PSC_AC97EVNT_OFFSET)
+#define PSC_AC97TXRX		(AC97_PSC_BASE + PSC_AC97TXRX_OFFSET)
+#define PSC_AC97CDC		(AC97_PSC_BASE + PSC_AC97CDC_OFFSET)
+#define PSC_AC97RST		(AC97_PSC_BASE + PSC_AC97RST_OFFSET)
+#define PSC_AC97GPO		(AC97_PSC_BASE + PSC_AC97GPO_OFFSET)
+#define PSC_AC97GPI		(AC97_PSC_BASE + PSC_AC97GPI_OFFSET)
+
+/* AC97 Config Register.
+*/
+#define PSC_AC97CFG_RT_MASK	(3 << 30)
+#define PSC_AC97CFG_RT_FIFO1	(0 << 30)
+#define PSC_AC97CFG_RT_FIFO2	(1 << 30)
+#define PSC_AC97CFG_RT_FIFO4	(2 << 30)
+#define PSC_AC97CFG_RT_FIFO8	(3 << 30)
+
+#define PSC_AC97CFG_TT_MASK	(3 << 28)
+#define PSC_AC97CFG_TT_FIFO1	(0 << 28)
+#define PSC_AC97CFG_TT_FIFO2	(1 << 28)
+#define PSC_AC97CFG_TT_FIFO4	(2 << 28)
+#define PSC_AC97CFG_TT_FIFO8	(3 << 28)
+
+#define PSC_AC97CFG_DD_DISABLE	(1 << 27)
+#define PSC_AC97CFG_DE_ENABLE	(1 << 26)
+#define PSC_AC97CFG_SE_ENABLE	(1 << 25)
+
+#define PSC_AC97CFG_LEN_MASK	(0xf << 21)
+#define PSC_AC97CFG_TXSLOT_MASK	(0x3ff << 11)
+#define PSC_AC97CFG_RXSLOT_MASK	(0x3ff << 1)
+#define PSC_AC97CFG_GE_ENABLE	(1)
+
+/* Enable slots 3-12.
+*/
+#define PSC_AC97CFG_TXSLOT_ENA(x)	(1 << (((x) - 3) + 11))
+#define PSC_AC97CFG_RXSLOT_ENA(x)	(1 << (((x) - 3) + 1))
+
+/* The word length equation is ((x) * 2) + 2, so choose 'x' appropriately.
+ * The only sensible numbers are 7, 9, or possibly 11.  Nah, just do the
+ * arithmetic in the macro.
+ */
+#define PSC_AC97CFG_SET_LEN(x)	(((((x)-2)/2) & 0xf) << 21)
+#define PSC_AC97CFG_GET_LEN(x)	(((((x) >> 21) & 0xf) * 2) + 2)
+
+/* AC97 Mask Register.
+*/
+#define PSC_AC97MSK_GR		(1 << 25)
+#define PSC_AC97MSK_CD		(1 << 24)
+#define PSC_AC97MSK_RR		(1 << 13)
+#define PSC_AC97MSK_RO		(1 << 12)
+#define PSC_AC97MSK_RU		(1 << 11)
+#define PSC_AC97MSK_TR		(1 << 10)
+#define PSC_AC97MSK_TO		(1 << 9)
+#define PSC_AC97MSK_TU		(1 << 8)
+#define PSC_AC97MSK_RD		(1 << 5)
+#define PSC_AC97MSK_TD		(1 << 4)
+#define PSC_AC97MSK_ALLMASK	(PSC_AC97MSK_GR | PSC_AC97MSK_CD | \
+				 PSC_AC97MSK_RR | PSC_AC97MSK_RO | \
+				 PSC_AC97MSK_RU | PSC_AC97MSK_TR | \
+				 PSC_AC97MSK_TO | PSC_AC97MSK_TU | \
+				 PSC_AC97MSK_RD | PSC_AC97MSK_TD)
+
+/* AC97 Protocol Control Register.
+*/
+#define PSC_AC97PCR_RC		(1 << 6)
+#define PSC_AC97PCR_RP		(1 << 5)
+#define PSC_AC97PCR_RS		(1 << 4)
+#define PSC_AC97PCR_TC		(1 << 2)
+#define PSC_AC97PCR_TP		(1 << 1)
+#define PSC_AC97PCR_TS		(1 << 0)
+
+/* AC97 Status register (read only).
+*/
+#define PSC_AC97STAT_CB		(1 << 26)
+#define PSC_AC97STAT_CP		(1 << 25)
+#define PSC_AC97STAT_CR		(1 << 24)
+#define PSC_AC97STAT_RF		(1 << 13)
+#define PSC_AC97STAT_RE		(1 << 12)
+#define PSC_AC97STAT_RR		(1 << 11)
+#define PSC_AC97STAT_TF		(1 << 10)
+#define PSC_AC97STAT_TE		(1 << 9)
+#define PSC_AC97STAT_TR		(1 << 8)
+#define PSC_AC97STAT_RB		(1 << 5)
+#define PSC_AC97STAT_TB		(1 << 4)
+#define PSC_AC97STAT_DI		(1 << 2)
+#define PSC_AC97STAT_DR		(1 << 1)
+#define PSC_AC97STAT_SR		(1 << 0)
+
+/* AC97 Event Register.
+*/
+#define PSC_AC97EVNT_GR		(1 << 25)
+#define PSC_AC97EVNT_CD		(1 << 24)
+#define PSC_AC97EVNT_RR		(1 << 13)
+#define PSC_AC97EVNT_RO		(1 << 12)
+#define PSC_AC97EVNT_RU		(1 << 11)
+#define PSC_AC97EVNT_TR		(1 << 10)
+#define PSC_AC97EVNT_TO		(1 << 9)
+#define PSC_AC97EVNT_TU		(1 << 8)
+#define PSC_AC97EVNT_RD		(1 << 5)
+#define PSC_AC97EVNT_TD		(1 << 4)
+
+/* CODEC Command Register.
+*/
+#define PSC_AC97CDC_RD		(1 << 25)
+#define PSC_AC97CDC_ID_MASK	(3 << 23)
+#define PSC_AC97CDC_INDX_MASK	(0x7f << 16)
+#define PSC_AC97CDC_ID(x)	(((x) & 0x3) << 23)
+#define PSC_AC97CDC_INDX(x)	(((x) & 0x7f) << 16)
+
+/* AC97 Reset Control Register.
+*/
+#define PSC_AC97RST_RST		(1 << 1)
+#define PSC_AC97RST_SNC		(1 << 0)
+
+
+/* PSC in I2S Mode.
+*/
+typedef struct	psc_i2s {
+	u32	psc_sel;
+	u32	psc_ctrl;
+	u32	psc_i2scfg;
+	u32	psc_i2smsk;
+	u32	psc_i2spcr;
+	u32	psc_i2sstat;
+	u32	psc_i2sevent;
+	u32	psc_i2stxrx;
+	u32	psc_i2sudf;
+} psc_i2s_t;
+
+/* I2S Config Register.
+*/
+#define PSC_I2SCFG_RT_MASK	(3 << 30)
+#define PSC_I2SCFG_RT_FIFO1	(0 << 30)
+#define PSC_I2SCFG_RT_FIFO2	(1 << 30)
+#define PSC_I2SCFG_RT_FIFO4	(2 << 30)
+#define PSC_I2SCFG_RT_FIFO8	(3 << 30)
+
+#define PSC_I2SCFG_TT_MASK	(3 << 28)
+#define PSC_I2SCFG_TT_FIFO1	(0 << 28)
+#define PSC_I2SCFG_TT_FIFO2	(1 << 28)
+#define PSC_I2SCFG_TT_FIFO4	(2 << 28)
+#define PSC_I2SCFG_TT_FIFO8	(3 << 28)
+
+#define PSC_I2SCFG_DD_DISABLE	(1 << 27)
+#define PSC_I2SCFG_DE_ENABLE	(1 << 26)
+#define PSC_I2SCFG_SET_WS(x)	(((((x) / 2) - 1) & 0x7f) << 16)
+#define PSC_I2SCFG_WI		(1 << 15)
+
+#define PSC_I2SCFG_DIV_MASK	(3 << 13)
+#define PSC_I2SCFG_DIV2		(0 << 13)
+#define PSC_I2SCFG_DIV4		(1 << 13)
+#define PSC_I2SCFG_DIV8		(2 << 13)
+#define PSC_I2SCFG_DIV16	(3 << 13)
+
+#define PSC_I2SCFG_BI		(1 << 12)
+#define PSC_I2SCFG_BUF		(1 << 11)
+#define PSC_I2SCFG_MLJ		(1 << 10)
+#define PSC_I2SCFG_XM		(1 << 9)
+
+/* The word length equation is simply LEN+1.
+ */
+#define PSC_I2SCFG_SET_LEN(x)	((((x) - 1) & 0x1f) << 4)
+#define PSC_I2SCFG_GET_LEN(x)	((((x) >> 4) & 0x1f) + 1)
+
+#define PSC_I2SCFG_LB		(1 << 2)
+#define PSC_I2SCFG_MLF		(1 << 1)
+#define PSC_I2SCFG_MS		(1 << 0)
+
+/* I2S Mask Register.
+*/
+#define PSC_I2SMSK_RR		(1 << 13)
+#define PSC_I2SMSK_RO		(1 << 12)
+#define PSC_I2SMSK_RU		(1 << 11)
+#define PSC_I2SMSK_TR		(1 << 10)
+#define PSC_I2SMSK_TO		(1 << 9)
+#define PSC_I2SMSK_TU		(1 << 8)
+#define PSC_I2SMSK_RD		(1 << 5)
+#define PSC_I2SMSK_TD		(1 << 4)
+#define PSC_I2SMSK_ALLMASK	(PSC_I2SMSK_RR | PSC_I2SMSK_RO | \
+				 PSC_I2SMSK_RU | PSC_I2SMSK_TR | \
+				 PSC_I2SMSK_TO | PSC_I2SMSK_TU | \
+				 PSC_I2SMSK_RD | PSC_I2SMSK_TD)
+
+/* I2S Protocol Control Register.
+*/
+#define PSC_I2SPCR_RC		(1 << 6)
+#define PSC_I2SPCR_RP		(1 << 5)
+#define PSC_I2SPCR_RS		(1 << 4)
+#define PSC_I2SPCR_TC		(1 << 2)
+#define PSC_I2SPCR_TP		(1 << 1)
+#define PSC_I2SPCR_TS		(1 << 0)
+
+/* I2S Status register (read only).
+*/
+#define PSC_I2SSTAT_RF		(1 << 13)
+#define PSC_I2SSTAT_RE		(1 << 12)
+#define PSC_I2SSTAT_RR		(1 << 11)
+#define PSC_I2SSTAT_TF		(1 << 10)
+#define PSC_I2SSTAT_TE		(1 << 9)
+#define PSC_I2SSTAT_TR		(1 << 8)
+#define PSC_I2SSTAT_RB		(1 << 5)
+#define PSC_I2SSTAT_TB		(1 << 4)
+#define PSC_I2SSTAT_DI		(1 << 2)
+#define PSC_I2SSTAT_DR		(1 << 1)
+#define PSC_I2SSTAT_SR		(1 << 0)
+
+/* I2S Event Register.
+*/
+#define PSC_I2SEVNT_RR		(1 << 13)
+#define PSC_I2SEVNT_RO		(1 << 12)
+#define PSC_I2SEVNT_RU		(1 << 11)
+#define PSC_I2SEVNT_TR		(1 << 10)
+#define PSC_I2SEVNT_TO		(1 << 9)
+#define PSC_I2SEVNT_TU		(1 << 8)
+#define PSC_I2SEVNT_RD		(1 << 5)
+#define PSC_I2SEVNT_TD		(1 << 4)
+
+/* PSC in SPI Mode.
+*/
+typedef struct	psc_spi {
+	u32	psc_sel;
+	u32	psc_ctrl;
+	u32	psc_spicfg;
+	u32	psc_spimsk;
+	u32	psc_spipcr;
+	u32	psc_spistat;
+	u32	psc_spievent;
+	u32	psc_spitxrx;
+} psc_spi_t;
+
+/* SPI Config Register.
+*/
+#define PSC_SPICFG_RT_MASK	(3 << 30)
+#define PSC_SPICFG_RT_FIFO1	(0 << 30)
+#define PSC_SPICFG_RT_FIFO2	(1 << 30)
+#define PSC_SPICFG_RT_FIFO4	(2 << 30)
+#define PSC_SPICFG_RT_FIFO8	(3 << 30)
+
+#define PSC_SPICFG_TT_MASK	(3 << 28)
+#define PSC_SPICFG_TT_FIFO1	(0 << 28)
+#define PSC_SPICFG_TT_FIFO2	(1 << 28)
+#define PSC_SPICFG_TT_FIFO4	(2 << 28)
+#define PSC_SPICFG_TT_FIFO8	(3 << 28)
+
+#define PSC_SPICFG_DD_DISABLE	(1 << 27)
+#define PSC_SPICFG_DE_ENABLE	(1 << 26)
+#define PSC_SPICFG_CLR_BAUD(x)	((x) & ~((0x3f) << 15))
+#define PSC_SPICFG_SET_BAUD(x)	(((x) & 0x3f) << 15)
+
+#define PSC_SPICFG_SET_DIV(x)	(((x) & 0x03) << 13)
+#define PSC_SPICFG_DIV2		0
+#define PSC_SPICFG_DIV4		1
+#define PSC_SPICFG_DIV8		2
+#define PSC_SPICFG_DIV16	3
+
+#define PSC_SPICFG_BI		(1 << 12)
+#define PSC_SPICFG_PSE		(1 << 11)
+#define PSC_SPICFG_CGE		(1 << 10)
+#define PSC_SPICFG_CDE		(1 << 9)
+
+#define PSC_SPICFG_CLR_LEN(x)	((x) & ~((0x1f) << 4))
+#define PSC_SPICFG_SET_LEN(x)	(((x-1) & 0x1f) << 4)
+
+#define PSC_SPICFG_LB		(1 << 3)
+#define PSC_SPICFG_MLF		(1 << 1)
+#define PSC_SPICFG_MO		(1 << 0)
+
+/* SPI Mask Register.
+*/
+#define PSC_SPIMSK_MM		(1 << 16)
+#define PSC_SPIMSK_RR		(1 << 13)
+#define PSC_SPIMSK_RO		(1 << 12)
+#define PSC_SPIMSK_RU		(1 << 11)
+#define PSC_SPIMSK_TR		(1 << 10)
+#define PSC_SPIMSK_TO		(1 << 9)
+#define PSC_SPIMSK_TU		(1 << 8)
+#define PSC_SPIMSK_SD		(1 << 5)
+#define PSC_SPIMSK_MD		(1 << 4)
+#define PSC_SPIMSK_ALLMASK	(PSC_SPIMSK_MM | PSC_SPIMSK_RR | \
+				 PSC_SPIMSK_RO | PSC_SPIMSK_TO | \
+				 PSC_SPIMSK_TU | PSC_SPIMSK_SD | \
+				 PSC_SPIMSK_MD)
+
+/* SPI Protocol Control Register.
+*/
+#define PSC_SPIPCR_RC		(1 << 6)
+#define PSC_SPIPCR_SP		(1 << 5)
+#define PSC_SPIPCR_SS		(1 << 4)
+#define PSC_SPIPCR_TC		(1 << 2)
+#define PSC_SPIPCR_MS		(1 << 0)
+
+/* SPI Status register (read only).
+*/
+#define PSC_SPISTAT_RF		(1 << 13)
+#define PSC_SPISTAT_RE		(1 << 12)
+#define PSC_SPISTAT_RR		(1 << 11)
+#define PSC_SPISTAT_TF		(1 << 10)
+#define PSC_SPISTAT_TE		(1 << 9)
+#define PSC_SPISTAT_TR		(1 << 8)
+#define PSC_SPISTAT_SB		(1 << 5)
+#define PSC_SPISTAT_MB		(1 << 4)
+#define PSC_SPISTAT_DI		(1 << 2)
+#define PSC_SPISTAT_DR		(1 << 1)
+#define PSC_SPISTAT_SR		(1 << 0)
+
+/* SPI Event Register.
+*/
+#define PSC_SPIEVNT_MM		(1 << 16)
+#define PSC_SPIEVNT_RR		(1 << 13)
+#define PSC_SPIEVNT_RO		(1 << 12)
+#define PSC_SPIEVNT_RU		(1 << 11)
+#define PSC_SPIEVNT_TR		(1 << 10)
+#define PSC_SPIEVNT_TO		(1 << 9)
+#define PSC_SPIEVNT_TU		(1 << 8)
+#define PSC_SPIEVNT_SD		(1 << 5)
+#define PSC_SPIEVNT_MD		(1 << 4)
+
+/* Transmit register control.
+*/
+#define PSC_SPITXRX_LC		(1 << 29)
+#define PSC_SPITXRX_SR		(1 << 28)
+
+/* PSC in SMBus (I2C) Mode.
+*/
+typedef struct	psc_smb {
+	u32	psc_sel;
+	u32	psc_ctrl;
+	u32	psc_smbcfg;
+	u32	psc_smbmsk;
+	u32	psc_smbpcr;
+	u32	psc_smbstat;
+	u32	psc_smbevnt;
+	u32	psc_smbtxrx;
+	u32	psc_smbtmr;
+} psc_smb_t;
+
+/* SMBus Config Register.
+*/
+#define PSC_SMBCFG_RT_MASK	(3 << 30)
+#define PSC_SMBCFG_RT_FIFO1	(0 << 30)
+#define PSC_SMBCFG_RT_FIFO2	(1 << 30)
+#define PSC_SMBCFG_RT_FIFO4	(2 << 30)
+#define PSC_SMBCFG_RT_FIFO8	(3 << 30)
+
+#define PSC_SMBCFG_TT_MASK	(3 << 28)
+#define PSC_SMBCFG_TT_FIFO1	(0 << 28)
+#define PSC_SMBCFG_TT_FIFO2	(1 << 28)
+#define PSC_SMBCFG_TT_FIFO4	(2 << 28)
+#define PSC_SMBCFG_TT_FIFO8	(3 << 28)
+
+#define PSC_SMBCFG_DD_DISABLE	(1 << 27)
+#define PSC_SMBCFG_DE_ENABLE	(1 << 26)
+
+#define PSC_SMBCFG_SET_DIV(x)	(((x) & 0x03) << 13)
+#define PSC_SMBCFG_DIV2		0
+#define PSC_SMBCFG_DIV4		1
+#define PSC_SMBCFG_DIV8		2
+#define PSC_SMBCFG_DIV16	3
+
+#define PSC_SMBCFG_GCE		(1 << 9)
+#define PSC_SMBCFG_SFM		(1 << 8)
+
+#define PSC_SMBCFG_SET_SLV(x)	(((x) & 0x7f) << 1)
+
+/* SMBus Mask Register.
+*/
+#define PSC_SMBMSK_DN		(1 << 30)
+#define PSC_SMBMSK_AN		(1 << 29)
+#define PSC_SMBMSK_AL		(1 << 28)
+#define PSC_SMBMSK_RR		(1 << 13)
+#define PSC_SMBMSK_RO		(1 << 12)
+#define PSC_SMBMSK_RU		(1 << 11)
+#define PSC_SMBMSK_TR		(1 << 10)
+#define PSC_SMBMSK_TO		(1 << 9)
+#define PSC_SMBMSK_TU		(1 << 8)
+#define PSC_SMBMSK_SD		(1 << 5)
+#define PSC_SMBMSK_MD		(1 << 4)
+#define PSC_SMBMSK_ALLMASK	(PSC_SMBMSK_DN | PSC_SMBMSK_AN | \
+				 PSC_SMBMSK_AL | PSC_SMBMSK_RR | \
+				 PSC_SMBMSK_RO | PSC_SMBMSK_TO | \
+				 PSC_SMBMSK_TU | PSC_SMBMSK_SD | \
+				 PSC_SMBMSK_MD)
+
+/* SMBus Protocol Control Register.
+*/
+#define PSC_SMBPCR_DC		(1 << 2)
+#define PSC_SMBPCR_MS		(1 << 0)
+
+/* SMBus Status register (read only).
+*/
+#define PSC_SMBSTAT_BB		(1 << 28)
+#define PSC_SMBSTAT_RF		(1 << 13)
+#define PSC_SMBSTAT_RE		(1 << 12)
+#define PSC_SMBSTAT_RR		(1 << 11)
+#define PSC_SMBSTAT_TF		(1 << 10)
+#define PSC_SMBSTAT_TE		(1 << 9)
+#define PSC_SMBSTAT_TR		(1 << 8)
+#define PSC_SMBSTAT_SB		(1 << 5)
+#define PSC_SMBSTAT_MB		(1 << 4)
+#define PSC_SMBSTAT_DI		(1 << 2)
+#define PSC_SMBSTAT_DR		(1 << 1)
+#define PSC_SMBSTAT_SR		(1 << 0)
+
+/* SMBus Event Register.
+*/
+#define PSC_SMBEVNT_DN		(1 << 30)
+#define PSC_SMBEVNT_AN		(1 << 29)
+#define PSC_SMBEVNT_AL		(1 << 28)
+#define PSC_SMBEVNT_RR		(1 << 13)
+#define PSC_SMBEVNT_RO		(1 << 12)
+#define PSC_SMBEVNT_RU		(1 << 11)
+#define PSC_SMBEVNT_TR		(1 << 10)
+#define PSC_SMBEVNT_TO		(1 << 9)
+#define PSC_SMBEVNT_TU		(1 << 8)
+#define PSC_SMBEVNT_SD		(1 << 5)
+#define PSC_SMBEVNT_MD		(1 << 4)
+#define PSC_SMBEVNT_ALLCLR	(PSC_SMBEVNT_DN | PSC_SMBEVNT_AN | \
+				 PSC_SMBEVNT_AL | PSC_SMBEVNT_RR | \
+				 PSC_SMBEVNT_RO | PSC_SMBEVNT_TO | \
+				 PSC_SMBEVNT_TU | PSC_SMBEVNT_SD | \
+				 PSC_SMBEVNT_MD)
+
+/* Transmit register control.
+*/
+#define PSC_SMBTXRX_RSR		(1 << 30)
+#define PSC_SMBTXRX_STP		(1 << 29)
+#define PSC_SMBTXRX_DATAMASK	(0xff)
+
+/* SMBus protocol timers register.
+*/
+#define PSC_SMBTMR_SET_TH(x)	(((x) & 0x3) << 30)
+#define PSC_SMBTMR_SET_PS(x)	(((x) & 0x1f) << 25)
+#define PSC_SMBTMR_SET_PU(x)	(((x) & 0x1f) << 20)
+#define PSC_SMBTMR_SET_SH(x)	(((x) & 0x1f) << 15)
+#define PSC_SMBTMR_SET_SU(x)	(((x) & 0x1f) << 10)
+#define PSC_SMBTMR_SET_CL(x)	(((x) & 0x1f) << 5)
+#define PSC_SMBTMR_SET_CH(x)	(((x) & 0x1f) << 0)
+
+
+#endif /* _AU1000_PSC_H_ */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/checksum.h linux-2.4.29-pre3/include/asm-mips/checksum.h
--- linux-2.4.28/include/asm-mips/checksum.h	2003-08-25 11:44:43.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/checksum.h	2004-12-22 16:05:36.046939360 +0000
@@ -123,10 +123,6 @@ static inline unsigned short ip_fast_csu
 	return csum_fold(csum);
 }
 
-/*
- * computes the checksum of the TCP/UDP pseudo-header
- * returns a 16-bit checksum, already complemented
- */
 static inline unsigned long csum_tcpudp_nofold(unsigned long saddr,
                                                unsigned long daddr,
                                                unsigned short len,
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/compiler.h linux-2.4.29-pre3/include/asm-mips/compiler.h
--- linux-2.4.28/include/asm-mips/compiler.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/compiler.h	2004-12-22 16:07:53.999967312 +0000
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2004  Maciej W. Rozycki
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#ifndef _ASM_COMPILER_H
+#define _ASM_COMPILER_H
+
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+#define GCC_REG_ACCUM "$0"
+#else
+#define GCC_REG_ACCUM "accum"
+#endif
+
+#endif /* _ASM_COMPILER_H */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/cpu.h linux-2.4.29-pre3/include/asm-mips/cpu.h
--- linux-2.4.28/include/asm-mips/cpu.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/cpu.h	2004-12-22 16:05:49.009968680 +0000
@@ -173,7 +173,8 @@
 #define CPU_VR4133		56
 #define CPU_AU1550		57
 #define CPU_24K			58
-#define CPU_LAST		58
+#define CPU_AU1200		59
+#define CPU_LAST		59
 
 /*
  * ISA Level encodings
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/db1x00.h linux-2.4.29-pre3/include/asm-mips/db1x00.h
--- linux-2.4.28/include/asm-mips/db1x00.h	2003-08-25 11:44:43.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/db1x00.h	2004-12-22 16:05:31.000000000 +0000
@@ -27,21 +27,42 @@
 #ifndef __ASM_DB1X00_H
 #define __ASM_DB1X00_H
 
+#ifdef CONFIG_MIPS_DB1550
+#define BCSR_KSEG1_ADDR 0xAF000000
+#define NAND_PHYS_ADDR   0x20000000
+#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
+#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
+#define SPI_PSC_BASE        PSC0_BASE_ADDR
+#define AC97_PSC_BASE       PSC1_BASE_ADDR
+#define SMBUS_PSC_BASE      PSC2_BASE_ADDR
+#define I2S_PSC_BASE        PSC3_BASE_ADDR
+
+#else
+#define BCSR_KSEG1_ADDR 0xAE000000
+#endif
 
 /*
  * Overlay data structure of the Db1x00 board registers.
- * Registers located at physical 1E0000xx, KSEG1 0xAE0000xx
+ * Registers located at physical 0E0000xx, KSEG1 0xAE0000xx
  */
 typedef volatile struct
 {
-	/*00*/	unsigned long whoami;
-	/*04*/	unsigned long status;
-	/*08*/	unsigned long switches;
-	/*0C*/	unsigned long resets;
-	/*10*/	unsigned long pcmcia;
-	/*14*/	unsigned long specific;
-	/*18*/	unsigned long leds;
-	/*1C*/	unsigned long swreset;
+	/*00*/	unsigned short whoami;
+			unsigned short reserved0;
+	/*04*/	unsigned short status;
+			unsigned short reserved1;
+	/*08*/	unsigned short switches;
+			unsigned short reserved2;
+	/*0C*/	unsigned short resets;
+			unsigned short reserved3;
+	/*10*/	unsigned short pcmcia;
+			unsigned short reserved4;
+	/*14*/	unsigned short specific;
+			unsigned short reserved5;
+	/*18*/	unsigned short leds;
+			unsigned short reserved6;
+	/*1C*/	unsigned short swreset;
+			unsigned short reserved7;
 
 } BCSR;
 
@@ -93,9 +114,13 @@ typedef volatile struct
 #define BCSR_PCMCIA_PC1RST		0x8000
 
 #define BCSR_BOARD_PCIM66EN		0x0001
+#define BCSR_BOARD_SD0_PWR		0x0040
+#define BCSR_BOARD_SD1_PWR		0x0080
 #define BCSR_BOARD_PCIM33		0x0100
 #define BCSR_BOARD_GPIO200RST		0x0400
 #define BCSR_BOARD_PCICFG		0x1000
+#define BCSR_BOARD_SD0_WP		0x4000
+#define BCSR_BOARD_SD1_WP		0x8000
 
 #define BCSR_LEDS_DECIMALS		0x0003
 #define BCSR_LEDS_LED0			0x0100
@@ -122,4 +147,48 @@ typedef volatile struct
 #define DB1X00_USER_ONLY
 #endif
 
+/* SD controller macros */
+/*
+ * Detect card.
+ */
+#define mmc_card_inserted(_n_, _res_) \
+	do { \
+		BCSR * const bcsr = (BCSR *)0xAE000000; \
+		unsigned long mmc_wp, board_specific; \
+		if ((_n_)) { \
+			mmc_wp = BCSR_BOARD_SD1_WP; \
+		} else { \
+			mmc_wp = BCSR_BOARD_SD0_WP; \
+		} \
+		board_specific = au_readl((unsigned long)(&bcsr->specific)); \
+		if (!(board_specific & mmc_wp)) {/* low means card present */ \
+			*(int *)(_res_) = 1; \
+		} else { \
+			*(int *)(_res_) = 0; \
+		} \
+	} while (0)
+
+/*
+ * Apply power to card slot(s).
+ */
+#define mmc_power_on(_n_) \
+	do { \
+		BCSR * const bcsr = (BCSR *)0xAE000000; \
+		unsigned long mmc_pwr, mmc_wp, board_specific; \
+		if ((_n_)) { \
+			mmc_pwr = BCSR_BOARD_SD1_PWR; \
+			mmc_wp = BCSR_BOARD_SD1_WP; \
+		} else { \
+			mmc_pwr = BCSR_BOARD_SD0_PWR; \
+			mmc_wp = BCSR_BOARD_SD0_WP; \
+		} \
+		board_specific = au_readl((unsigned long)(&bcsr->specific)); \
+		if (!(board_specific & mmc_wp)) {/* low means card present */ \
+			board_specific |= mmc_pwr; \
+			au_writel(board_specific, (int)(&bcsr->specific)); \
+			au_sync(); \
+		} \
+	} while (0)
+
 #endif /* __ASM_DB1X00_H */
+
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/dec/prom.h linux-2.4.29-pre3/include/asm-mips/dec/prom.h
--- linux-2.4.28/include/asm-mips/dec/prom.h	2003-08-25 11:44:43.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/dec/prom.h	2004-12-22 16:07:20.144114184 +0000
@@ -164,4 +164,7 @@ extern void prom_meminit(u32);
 extern void prom_identify_arch(u32);
 extern void prom_init_cmdline(s32, s32 *, u32);
 
+extern void register_prom_console(void);
+extern void unregister_prom_console(void);
+
 #endif /* __ASM_DEC_PROM_H */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/dec/serial.h linux-2.4.29-pre3/include/asm-mips/dec/serial.h
--- linux-2.4.28/include/asm-mips/dec/serial.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/dec/serial.h	2004-12-22 16:07:00.954031520 +0000
@@ -0,0 +1,36 @@
+/*
+ *	include/asm-mips/dec/serial.h
+ *
+ *	Definitions common to all DECstation serial devices.
+ *
+ *	Copyright (C) 2004  Maciej W. Rozycki
+ *
+ *	Based on bits extracted from drivers/tc/zs.h for which
+ *	the following copyrights apply:
+ *
+ *	Copyright (C) 1995  David S. Miller (davem@caip.rutgers.edu)
+ *	Copyright (C) 1996  Paul Mackerras (Paul.Mackerras@cs.anu.edu.au)
+ *	Copyright (C)       Harald Koerfgen
+ *
+ *	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 __ASM_MIPS_DEC_SERIAL_H
+#define __ASM_MIPS_DEC_SERIAL_H
+
+struct dec_serial_hook {
+	int (*init_channel)(void *handle);
+	void (*init_info)(void *handle);
+	void (*rx_char)(unsigned char ch, unsigned char fl);
+	int (*poll_rx_char)(void *handle);
+	int (*poll_tx_char)(void *handle, unsigned char ch);
+	unsigned int cflags;
+};
+
+extern int register_dec_serial_hook(unsigned int channel,
+				    struct dec_serial_hook *hook);
+extern int unregister_dec_serial_hook(unsigned int channel);
+
+#endif /* __ASM_MIPS_DEC_SERIAL_H */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/delay.h linux-2.4.29-pre3/include/asm-mips/delay.h
--- linux-2.4.28/include/asm-mips/delay.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/delay.h	2004-12-22 16:07:42.026787512 +0000
@@ -12,6 +12,8 @@
 #include <linux/config.h>
 #include <linux/param.h>
 
+#include <asm/compiler.h>
+
 extern unsigned long loops_per_jiffy;
 
 static __inline__ void __delay(unsigned long loops)
@@ -45,8 +47,9 @@ static __inline__ void __udelay(unsigned
 	usecs *= (unsigned long) (((0x8000000000000000ULL / (500000 / HZ)) +
 	                           0x80000000ULL) >> 32);
 	__asm__("multu\t%2,%3"
-		:"=h" (usecs), "=l" (lo)
-		:"r" (usecs),"r" (lpj));
+		: "=h" (usecs), "=l" (lo)
+		: "r" (usecs), "r" (lpj)
+		: GCC_REG_ACCUM);
 	__delay(usecs);
 }
 
@@ -60,8 +63,9 @@ static __inline__ void __ndelay(unsigned
 	nsecs *= (unsigned long) (((0x8000000000000000ULL / (500000000 / HZ)) +
 	                           0x80000000ULL) >> 32);
 	__asm__("multu\t%2,%3"
-		:"=h" (nsecs), "=l" (lo)
-		:"r" (nsecs),"r" (lpj));
+		: "=h" (nsecs), "=l" (lo)
+		: "r" (nsecs), "r" (lpj)
+		: GCC_REG_ACCUM);
 	__delay(nsecs);
 }
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/div64.h linux-2.4.29-pre3/include/asm-mips/div64.h
--- linux-2.4.28/include/asm-mips/div64.h	2003-08-25 11:44:43.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/div64.h	2004-12-22 16:07:12.598261328 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2000  Maciej W. Rozycki
+ * Copyright (C) 2000, 2004  Maciej W. Rozycki
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -8,6 +8,8 @@
 #ifndef _ASM_DIV64_H
 #define _ASM_DIV64_H
 
+#include <asm/compiler.h>
+
 /*
  * No traps on overflows for any of these...
  */
@@ -64,7 +66,8 @@
 	if (__high) \
 		__asm__("divu	$0, %z2, %z3" \
 			: "=h" (__upper), "=l" (__high) \
-			: "Jr" (__high), "Jr" (__base)); \
+			: "Jr" (__high), "Jr" (__base) \
+			: GCC_REG_ACCUM); \
 	\
 	__mod = do_div64_32(__low, __upper, __low, __base); \
 	\
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/mipsregs.h linux-2.4.29-pre3/include/asm-mips/mipsregs.h
--- linux-2.4.28/include/asm-mips/mipsregs.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/mipsregs.h	2004-12-22 16:06:44.834482064 +0000
@@ -632,6 +632,24 @@ do {									\
 } while (0)
 
 /*
+ * On RM7000/RM9000 these are uses to access cop0 set 1 registers
+ */
+#define __read_32bit_c0_ctrl_register(source)				\
+({ int __res;								\
+	__asm__ __volatile__(						\
+		"cfc0\t%0, " #source "\n\t"				\
+		: "=r" (__res));					\
+	__res;								\
+})
+
+#define __write_32bit_c0_ctrl_register(register, value)			\
+do {									\
+	__asm__ __volatile__(						\
+		"ctc0\t%z0, " #register "\n\t"				\
+		: : "Jr" ((unsigned int)value));			\
+} while (0)
+
+/*
  * These versions are only needed for systems with more than 38 bits of
  * physical address space running the 32-bit kernel.  That's none atm :-)
  */
@@ -788,12 +806,30 @@ do {									\
 #define read_c0_xcontext()	__read_ulong_c0_register($20, 0)
 #define write_c0_xcontext(val)	__write_ulong_c0_register($20, 0, val)
 
-#define read_c0_intcontrol()	__read_32bit_c0_register($20, 1)
-#define write_c0_intcontrol(val) __write_32bit_c0_register($20, 1, val)
+#define read_c0_intcontrol()	__read_32bit_c0_ctrl_register($20)
+#define write_c0_intcontrol(val) __write_32bit_c0_ctrl_register($20, val)
 
 #define read_c0_framemask()	__read_32bit_c0_register($21, 0)
 #define write_c0_framemask(val)	__write_32bit_c0_register($21, 0, val)
 
+#define read_c0_diag()		__read_32bit_c0_register($22, 0)
+#define write_c0_diag(val)	__write_32bit_c0_register($22, 0, val)
+
+#define read_c0_diag1()		__read_32bit_c0_register($22, 1)
+#define write_c0_diag1(val)	__write_32bit_c0_register($22, 1, val)
+
+#define read_c0_diag2()		__read_32bit_c0_register($22, 2)
+#define write_c0_diag2(val)	__write_32bit_c0_register($22, 2, val)
+
+#define read_c0_diag3()		__read_32bit_c0_register($22, 3)
+#define write_c0_diag3(val)	__write_32bit_c0_register($22, 3, val)
+
+#define read_c0_diag4()		__read_32bit_c0_register($22, 4)
+#define write_c0_diag4(val)	__write_32bit_c0_register($22, 4, val)
+
+#define read_c0_diag5()		__read_32bit_c0_register($22, 5)
+#define write_c0_diag5(val)	__write_32bit_c0_register($22, 5, val)
+
 #define read_c0_debug()		__read_32bit_c0_register($23, 0)
 #define write_c0_debug(val)	__write_32bit_c0_register($23, 0, val)
 
@@ -879,7 +915,7 @@ static inline void tlb_write_random(void
 /*
  * Manipulate bits in a c0 register.
  */
-#define __BUILD_SET_C0(name,register)				\
+#define __BUILD_SET_C0(name)					\
 static inline unsigned int					\
 set_c0_##name(unsigned int set)					\
 {								\
@@ -917,9 +953,10 @@ change_c0_##name(unsigned int change, un
 	return res;						\
 }
 
-__BUILD_SET_C0(status,CP0_STATUS)
-__BUILD_SET_C0(cause,CP0_CAUSE)
-__BUILD_SET_C0(config,CP0_CONFIG)
+__BUILD_SET_C0(status)
+__BUILD_SET_C0(cause)
+__BUILD_SET_C0(config)
+__BUILD_SET_C0(intcontrol)
 
 #endif /* !__ASSEMBLY__ */
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/mmu_context.h linux-2.4.29-pre3/include/asm-mips/mmu_context.h
--- linux-2.4.28/include/asm-mips/mmu_context.h	2003-08-25 11:44:43.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/mmu_context.h	2004-12-22 16:06:39.377311680 +0000
@@ -33,13 +33,18 @@ extern unsigned long pgd_current[];
 
 #define cpu_context(cpu, mm)	((mm)->context[cpu])
 #define cpu_asid(cpu, mm)	(cpu_context((cpu), (mm)) & ASID_MASK)
-#define asid_cache(cpu)		cpu_data[cpu].asid_cache
+#define asid_cache(cpu)		(cpu_data[cpu].asid_cache)
 
 #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
 
 #define ASID_INC	0x40
 #define ASID_MASK	0xfc0
 
+#elif defined(CONFIG_CPU_RM9000)
+
+#define ASID_INC	0x1
+#define ASID_MASK	0xfff
+
 #else /* FIXME: not correct for R6000, R8000 */
 
 #define ASID_INC	0x1
@@ -136,7 +141,7 @@ activate_mm(struct mm_struct *prev, stru
 	write_c0_entryhi(cpu_context(cpu, next));
 	TLBMISS_HANDLER_SETUP_PGD(next->pgd);
 
-	/* mark mmu ownership change */	
+	/* mark mmu ownership change */
 	clear_bit(cpu, &prev->cpu_vm_mask);
 	set_bit(cpu, &next->cpu_vm_mask);
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/param.h linux-2.4.29-pre3/include/asm-mips/param.h
--- linux-2.4.28/include/asm-mips/param.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/param.h	2004-12-22 16:05:55.324008800 +0000
@@ -12,6 +12,8 @@
 
 #include <linux/config.h>
 
+#include <asm/compiler.h>
+
 #ifdef CONFIG_DECSTATION
    /*
     * log2(HZ), change this here if you want another HZ value. This is also
@@ -28,8 +30,9 @@
    ({ unsigned long __res;			\
       unsigned long __lo;			\
 	__asm__("multu\t%2,%3\n\t"		\
-		:"=h" (__res), "=l" (__lo)	\
-		:"r" (a), "r" (QUOTIENT));	\
+		: "=h" (__res), "=l" (__lo)	\
+		: "r" (a), "r" (QUOTIENT)	\
+		: GCC_REG_ACCUM);		\
 	(__typeof__(a)) __res;})
 
 #else /* Not a DECstation  */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/pb1550.h linux-2.4.29-pre3/include/asm-mips/pb1550.h
--- linux-2.4.28/include/asm-mips/pb1550.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/pb1550.h	2004-12-22 16:05:32.000000000 +0000
@@ -0,0 +1,168 @@
+/*
+ * AMD Alchemy Semi PB1550 Referrence Board
+ * Board Registers defines.
+ *
+ * Copyright 2004 Embedded Edge LLC.
+ *
+ * ########################################################################
+ *
+ *  This program is free software; you can distribute it and/or modify it
+ *  under the terms of the GNU General Public License (Version 2) as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope it will be useful, but WITHOUT
+ *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ *  for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ *
+ */
+#ifndef __ASM_PB1550_H
+#define __ASM_PB1550_H
+
+#include <linux/types.h>
+
+#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX
+#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX
+#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC3_TX
+#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC3_RX
+
+#define SPI_PSC_BASE        PSC0_BASE_ADDR
+#define AC97_PSC_BASE       PSC1_BASE_ADDR
+#define SMBUS_PSC_BASE      PSC2_BASE_ADDR
+#define I2S_PSC_BASE        PSC3_BASE_ADDR
+
+#define BCSR_PHYS_ADDR 0xAF000000
+
+typedef volatile struct
+{
+	/*00*/	u16 whoami;
+		u16 reserved0;
+	/*04*/	u16 status;
+		u16 reserved1;
+	/*08*/	u16 switches;
+		u16 reserved2;
+	/*0C*/	u16 resets;
+		u16 reserved3;
+	/*10*/	u16 pcmcia;
+		u16 reserved4;
+	/*14*/	u16 pci;
+		u16 reserved5;
+	/*18*/	u16 leds;
+		u16 reserved6;
+	/*1C*/	u16 system;
+		u16 reserved7;
+
+} BCSR;
+
+static BCSR * const bcsr = (BCSR *)BCSR_PHYS_ADDR;
+
+/*
+ * Register bit definitions for the BCSRs
+ */
+#define BCSR_WHOAMI_DCID	0x000F
+#define BCSR_WHOAMI_CPLD	0x00F0
+#define BCSR_WHOAMI_BOARD	0x0F00
+
+#define BCSR_STATUS_PCMCIA0VS	0x0003
+#define BCSR_STATUS_PCMCIA1VS	0x000C
+#define BCSR_STATUS_PCMCIA0FI	0x0010
+#define BCSR_STATUS_PCMCIA1FI	0x0020
+#define BCSR_STATUS_SWAPBOOT	0x0040
+#define BCSR_STATUS_SRAMWIDTH	0x0080
+#define BCSR_STATUS_FLASHBUSY	0x0100
+#define BCSR_STATUS_ROMBUSY	0x0200
+#define BCSR_STATUS_USBOTGID	0x0800
+#define BCSR_STATUS_U0RXD	0x1000
+#define BCSR_STATUS_U1RXD	0x2000
+#define BCSR_STATUS_U3RXD	0x8000
+
+#define BCSR_SWITCHES_OCTAL	0x00FF
+#define BCSR_SWITCHES_DIP_1	0x0080
+#define BCSR_SWITCHES_DIP_2	0x0040
+#define BCSR_SWITCHES_DIP_3	0x0020
+#define BCSR_SWITCHES_DIP_4	0x0010
+#define BCSR_SWITCHES_DIP_5	0x0008
+#define BCSR_SWITCHES_DIP_6	0x0004
+#define BCSR_SWITCHES_DIP_7	0x0002
+#define BCSR_SWITCHES_DIP_8	0x0001
+#define BCSR_SWITCHES_ROTARY	0x0F00
+
+#define BCSR_RESETS_PHY0	0x0001
+#define BCSR_RESETS_PHY1	0x0002
+#define BCSR_RESETS_DC		0x0004
+#define BCSR_RESETS_WSC		0x2000
+#define BCSR_RESETS_SPISEL	0x4000
+#define BCSR_RESETS_DMAREQ	0x8000
+
+#define BCSR_PCMCIA_PC0VPP	0x0003
+#define BCSR_PCMCIA_PC0VCC	0x000C
+#define BCSR_PCMCIA_PC0DRVEN	0x0010
+#define BCSR_PCMCIA_PC0RST	0x0080
+#define BCSR_PCMCIA_PC1VPP	0x0300
+#define BCSR_PCMCIA_PC1VCC	0x0C00
+#define BCSR_PCMCIA_PC1DRVEN	0x1000
+#define BCSR_PCMCIA_PC1RST	0x8000
+
+#define BCSR_PCI_M66EN		0x0001
+#define BCSR_PCI_M33		0x0100
+#define BCSR_PCI_EXTERNARB	0x0200
+#define BCSR_PCI_GPIO200RST	0x0400
+#define BCSR_PCI_CLKOUT		0x0800
+#define BCSR_PCI_CFGHOST	0x1000
+
+#define BCSR_LEDS_DECIMALS	0x00FF
+#define BCSR_LEDS_LED0		0x0100
+#define BCSR_LEDS_LED1		0x0200
+#define BCSR_LEDS_LED2		0x0400
+#define BCSR_LEDS_LED3		0x0800
+
+#define BCSR_SYSTEM_VDDI	0x001F
+#define BCSR_SYSTEM_POWEROFF	0x4000
+#define BCSR_SYSTEM_RESET	0x8000
+
+#define PCMCIA_MAX_SOCK 1
+#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
+
+/* VPP/VCC */
+#define SET_VCC_VPP(VCC, VPP, SLOT)\
+	((((VCC)<<2) | ((VPP)<<0)) << ((SLOT)*8))
+
+#if defined(CONFIG_MTD_PB1550_BOOT) && defined(CONFIG_MTD_PB1550_USER)
+#define PB1550_BOTH_BANKS
+#elif defined(CONFIG_MTD_PB1550_BOOT) && !defined(CONFIG_MTD_PB1550_USER)
+#define PB1550_BOOT_ONLY
+#elif !defined(CONFIG_MTD_PB1550_BOOT) && defined(CONFIG_MTD_PB1550_USER)
+#define PB1550_USER_ONLY
+#endif
+
+#define NAND_PHYS_ADDR   0x20000000
+/* Timing values as described in databook, * ns value stripped of 
+ * lower 2 bits.
+ * These defines are here rather than an SOC1550 generic file because 
+ * the parts chosen on another board may be different and may require 
+ * different timings.
+ */
+#define NAND_T_H			(18 >> 2)
+#define NAND_T_PUL			(30 >> 2)
+#define NAND_T_SU			(30 >> 2)
+#define NAND_T_WH			(30 >> 2)
+
+/* Bitfield shift amounts */
+#define NAND_T_H_SHIFT		0
+#define NAND_T_PUL_SHIFT	4
+#define NAND_T_SU_SHIFT		8
+#define NAND_T_WH_SHIFT		12
+
+#define NAND_TIMING	((NAND_T_H   & 0xF)	<< NAND_T_H_SHIFT)   | \
+			((NAND_T_PUL & 0xF)	<< NAND_T_PUL_SHIFT) | \
+			((NAND_T_SU  & 0xF)	<< NAND_T_SU_SHIFT)  | \
+			((NAND_T_WH  & 0xF)	<< NAND_T_WH_SHIFT)
+
+#endif /* __ASM_PB1550_H */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/pgtable-bits.h linux-2.4.29-pre3/include/asm-mips/pgtable-bits.h
--- linux-2.4.28/include/asm-mips/pgtable-bits.h	2003-08-25 11:44:44.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/pgtable-bits.h	2004-12-22 16:06:19.809286472 +0000
@@ -49,6 +49,10 @@
 #define _PAGE_SILENT_WRITE          (1<<2)
 #define _CACHE_MASK                 (7<<3)
 
+#ifdef CONFIG_SOC_AU1X00
+#define _CACHE_CACHABLE_COW         (3<<3)
+#endif
+
 /* MIPS32 defines only values 2 and 3. The rest are implementation
  * dependent.
  */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/prefetch.h linux-2.4.29-pre3/include/asm-mips/prefetch.h
--- linux-2.4.28/include/asm-mips/prefetch.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/prefetch.h	2004-12-22 16:06:01.408083880 +0000
@@ -21,8 +21,9 @@
  * RM7000 version 1.0 interprets all hints as Pref_Load; version 2.0 implements
  * Pref_PrepareForStore also.
  *
- * RM9000 is MIPS IV but implements prefetching like MIPS32/MIPS64;
- * it's Pref_WriteBackInvalidate is a nop.
+ * RM9000 is MIPS IV but implements prefetching like MIPS32/MIPS64; it's
+ * Pref_WriteBackInvalidate is a nop and Pref_PrepareForStore is broken in
+ * current versions due to erratum G105.
  *
  * VR7701 only implements the Load prefetch.
  *
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/processor.h linux-2.4.29-pre3/include/asm-mips/processor.h
--- linux-2.4.28/include/asm-mips/processor.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/processor.h	2004-12-22 16:05:32.000000000 +0000
@@ -96,6 +96,8 @@ struct cpuinfo_mips {
 #define cpu_has_dc_aliases	(cpu_data[0].dcache.flags & MIPS_CACHE_ALIASES)
 #define cpu_has_ic_fills_f_dc	(cpu_data[0].dcache.flags & MIPS_CACHE_IC_F_DC)
 #define cpu_has_64bits		(cpu_data[0].isa_level & MIPS_CPU_ISA_64BIT)
+#define cpu_has_64bit_zero_reg	(cpu_data[0].isa_level & MIPS_CPU_ISA_64BIT)
+#define cpu_has_64bit_gp_regs	0
 #define cpu_has_64bit_addresses	0
 #define cpu_has_subset_pcaches	(cpu_data[0].options & MIPS_CPU_SUBSET_CACHES)
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/serial.h linux-2.4.29-pre3/include/asm-mips/serial.h
--- linux-2.4.28/include/asm-mips/serial.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/serial.h	2004-12-22 16:06:45.474384784 +0000
@@ -160,6 +160,7 @@
 
 #ifdef CONFIG_AU1X00_UART
 #include <asm/au1000.h>
+#ifdef CONFIG_SOC_AU1000
 #define AU1000_SERIAL_PORT_DEFNS                              \
     { .baud_base = 0, .port = UART0_ADDR, .irq = AU1000_UART0_INT,  \
       .flags = STD_COM_FLAGS, .type = 1 },                        \
@@ -169,6 +170,44 @@
       .flags = STD_COM_FLAGS, .type = 1 },    \
     { .baud_base = 0, .port = UART3_ADDR, .irq = AU1000_UART3_INT,  \
       .flags = STD_COM_FLAGS, .type = 1 },
+#endif
+
+#ifdef CONFIG_SOC_AU1500
+#define AU1000_SERIAL_PORT_DEFNS                              \
+    { .baud_base = 0, .port = UART0_ADDR, .irq = AU1500_UART0_INT,  \
+      .flags = STD_COM_FLAGS, .type = 1 },                        \
+    { .baud_base = 0, .port = UART3_ADDR, .irq = AU1500_UART3_INT,  \
+      .flags = STD_COM_FLAGS, .type = 1 },
+#endif
+
+#ifdef CONFIG_SOC_AU1100
+#define AU1000_SERIAL_PORT_DEFNS                              \
+    { .baud_base = 0, .port = UART0_ADDR, .irq = AU1100_UART0_INT,  \
+      .flags = STD_COM_FLAGS, .type = 1 },                        \
+    { .baud_base = 0, .port = UART1_ADDR, .irq = AU1100_UART1_INT,  \
+      .flags = STD_COM_FLAGS, .type = 1 },     \
+    { .baud_base = 0, .port = UART3_ADDR, .irq = AU1100_UART3_INT,  \
+      .flags = STD_COM_FLAGS, .type = 1 },
+#endif
+
+#ifdef CONFIG_SOC_AU1550
+#define AU1000_SERIAL_PORT_DEFNS                              \
+    { .baud_base = 0, .port = UART0_ADDR, .irq = AU1550_UART0_INT,  \
+      .flags = STD_COM_FLAGS, .type = 1 },                        \
+    { .baud_base = 0, .port = UART1_ADDR, .irq = AU1550_UART1_INT,  \
+      .flags = STD_COM_FLAGS, .type = 1 },     \
+    { .baud_base = 0, .port = UART3_ADDR, .irq = AU1550_UART3_INT,  \
+      .flags = STD_COM_FLAGS, .type = 1 },
+#endif
+
+#ifdef CONFIG_SOC_AU1200
+#define AU1000_SERIAL_PORT_DEFNS                              \
+    { .baud_base = 0, .port = UART0_ADDR, .irq = AU1200_UART0_INT,  \
+      .flags = STD_COM_FLAGS, .type = 1 },                        \
+    { .baud_base = 0, .port = UART1_ADDR, .irq = AU1200_UART1_INT,  \
+      .flags = STD_COM_FLAGS, .type = 1 },
+#endif
+
 #else
 #define AU1000_SERIAL_PORT_DEFNS
 #endif
@@ -323,6 +362,24 @@
 #define MOMENCO_OCELOT_C_SERIAL_PORT_DEFNS
 #endif
 
+#ifdef CONFIG_PMC_STRETCH
+/* 16550 Compatible. FIXME: Need to get the defines below */
+
+#define PMC_STRETCH_BASE_BAUD 		( 1843200 / 16 )
+#define	PMC_STRETCH_IRQ			0
+#define	PMC_STRETCH_BASE_ADDRESS	0xbd110000
+
+#define	_PMC_STRETCH_SERIAL_INIT(int, base)				\
+	{ baud_base: PMC_STRETCH_BASE_BAUD, irq: int,			\
+	  flags: STD_COM_FLAGS,	iomem_base: (u8 *) base,		\
+	  iomem_reg_shift: 2, io_type: SERIAL_IO_MEM }
+
+#define	PMC_STRETCH_SERIAL_PORT_DEFNS						\
+	_PMC_STRETCH_SERIAL_INIT(PMC_STRETCH_IRQ, PMC_STRETCH_BASE_ADDRESS)
+#else
+#define	PMC_STRETCH_SERIAL_PORT_DEFNS
+#endif		
+
 #ifdef CONFIG_MOMENCO_JAGUAR_ATX
 /* Ordinary NS16552 duart with a 20MHz crystal.  */
 #define JAGUAR_ATX_BASE_BAUD ( 20000000 / 16 )
@@ -425,6 +482,7 @@
 	MOMENCO_OCELOT_G_SERIAL_PORT_DEFNS	\
 	MOMENCO_OCELOT_C_SERIAL_PORT_DEFNS	\
 	MOMENCO_JAGUAR_ATX_SERIAL_PORT_DEFNS	\
+	PMC_STRETCH_SERIAL_PORT_DEFNS		\
 	SEAD_SERIAL_PORT_DEFNS			\
 	STD_SERIAL_PORT_DEFNS			\
 	TITAN_SERIAL_PORT_DEFNS			\
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/sgiarcs.h linux-2.4.29-pre3/include/asm-mips/sgiarcs.h
--- linux-2.4.28/include/asm-mips/sgiarcs.h	2003-08-25 11:44:44.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/sgiarcs.h	2004-12-22 16:06:24.614555960 +0000
@@ -369,7 +369,7 @@ struct linux_smonblock {
 
 #define __arc_clobbers							\
 	"$2","$3" /* ... */, "$8","$9","$10","$11",			\
-	"$12","$13","$14","$15","$16","$24","25","$31"
+	"$12","$13","$14","$15","$16","$24","$25","$31"
 
 #define ARC_CALL0(dest)							\
 ({	long __res;							\
@@ -462,7 +462,7 @@ struct linux_smonblock {
 	long __vec = (long) romvec->dest;				\
 	__asm__ __volatile__(						\
 	"dsubu\t$29, 32\n\t"						\
-	"sw\t%6, 16($29)\n\t"						\
+	"sw\t%7, 16($29)\n\t"						\
 	"jalr\t%1\n\t"							\
 	"daddu\t$29, 32\n\t"						\
 	"move\t%0, $2"							\
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/siginfo.h linux-2.4.29-pre3/include/asm-mips/siginfo.h
--- linux-2.4.28/include/asm-mips/siginfo.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/siginfo.h	2004-12-22 16:06:53.535159360 +0000
@@ -3,11 +3,13 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1998, 1999, 2003 by Ralf Baechle
+ * Copyright (C) 1998, 1999, 2001, 03, 04 Ralf Baechle
+ * Copyright (C) 2000, 2001 Silicon Graphics, Inc.
  */
 #ifndef _ASM_SIGINFO_H
 #define _ASM_SIGINFO_H
 
+#include <linux/config.h>
 #include <linux/types.h>
 
 /* This structure matches IRIX 32/n32 ABIs for binary compatibility. */
@@ -21,12 +23,18 @@ typedef union sigval {
    has Linux extensions.  */
 
 #define SI_MAX_SIZE	128
+#ifdef CONFIG_MIPS32
 #define SI_PAD_SIZE	((SI_MAX_SIZE/sizeof(int)) - 3)
+#endif
+#ifdef CONFIG_MIPS64
+#define SI_PAD_SIZE	((SI_MAX_SIZE/sizeof(int)) - 4)
+#endif
 
 typedef struct siginfo {
 	int si_signo;
 	int si_code;
 	int si_errno;
+	int __pad0[SI_MAX_SIZE / sizeof(int) - SI_PAD_SIZE - 3];
 
 	union {
 		int _pad[SI_PAD_SIZE];
@@ -41,8 +49,8 @@ typedef struct siginfo {
 		struct {
 			pid_t _pid;		/* which child */
 			uid_t _uid;		/* sender's uid */
-			clock_t _utime;
 			int _status;		/* exit code */
+			clock_t _utime;
 			clock_t _stime;
 		} _sigchld;
 
@@ -61,7 +69,7 @@ typedef struct siginfo {
 
 		/* SIGPOLL, SIGXFSZ (To do ...)  */
 		struct {
-			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+			long _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
 			int _fd;
 		} _sigpoll;
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/smp.h linux-2.4.29-pre3/include/asm-mips/smp.h
--- linux-2.4.28/include/asm-mips/smp.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/smp.h	2004-12-22 16:05:50.816694016 +0000
@@ -106,7 +106,7 @@ void core_send_ipi(int cpu, unsigned int
  * Clear all undefined state in the cpu, set up sp and gp to the passed
  * values, and kick the cpu into smp_bootstrap();
  */
-void prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp);
+int prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp);
 
 /*
  *  After we've done initial boot, this function is called to allow the
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/uaccess.h linux-2.4.29-pre3/include/asm-mips/uaccess.h
--- linux-2.4.28/include/asm-mips/uaccess.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/uaccess.h	2004-12-22 16:05:32.000000000 +0000
@@ -3,19 +3,17 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 1997, 1998, 1999, 2000, 03 by Ralf Baechle
+ * Copyright (C) 1996, 1997, 1998, 1999, 2000, 03, 04 by Ralf Baechle
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  */
 #ifndef _ASM_UACCESS_H
 #define _ASM_UACCESS_H
 
+#include <linux/config.h>
 #include <linux/compiler.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
 
-#define STR(x)  __STR(x)
-#define __STR(x)  #x
-
 /*
  * The fs value determines whether argument validity checking should be
  * performed or not.  If get_fs() == USER_DS, checking is performed, with
@@ -23,15 +21,47 @@
  *
  * For historical reasons, these macros are grossly misnamed.
  */
-#define KERNEL_DS	((mm_segment_t) { (unsigned long) 0L })
-#define USER_DS		((mm_segment_t) { (unsigned long) -1L })
+#ifdef CONFIG_MIPS32
+
+#define __UA_LIMIT	0x80000000UL
+
+#define __UA_ADDR	".word"
+#define __UA_LA		"la"
+#define __UA_ADDU	"addu"
+#define __UA_t0		"$8"
+#define __UA_t1		"$9"
+
+#endif /* CONFIG_MIPS32 */
+
+#ifdef CONFIG_MIPS64
+
+#define __UA_LIMIT	(- TASK_SIZE)
+
+#define __UA_ADDR	".dword"
+#define __UA_LA		"dla"
+#define __UA_ADDU	"daddu"
+#define __UA_t0		"$12"
+#define __UA_t1		"$13"
+
+#endif /* CONFIG_MIPS64 */
+
+/*
+ * USER_DS is a bitmask that has the bits set that may not be set in a valid
+ * userspace address.  Note that we limit 32-bit userspace to 0x7fff8000 but
+ * the arithmetic we're doing only works if the limit is a power of two, so
+ * we use 0x80000000 here on 32-bit kernels.  If a process passes an invalid
+ * address in this range it's the process's problem, not ours :-)
+ */
+
+#define KERNEL_DS	((mm_segment_t) { 0UL })
+#define USER_DS		((mm_segment_t) { __UA_LIMIT })
 
 #define VERIFY_READ    0
 #define VERIFY_WRITE   1
 
-#define get_fs()        (current->thread.current_ds)
 #define get_ds()	(KERNEL_DS)
-#define set_fs(x)       (current->thread.current_ds=(x))
+#define get_fs()	(current->thread.current_ds)
+#define set_fs(x)	(current->thread.current_ds = (x))
 
 #define segment_eq(a,b)	((a).seg == (b).seg)
 
@@ -45,14 +75,12 @@
  *  - AND "size" doesn't have any high-bits set
  *  - AND "addr+size" doesn't have any high-bits set
  *  - OR we are in kernel mode.
+ *
+ * __ua_size() is a trick to avoid runtime checking of positive constant
+ * sizes; for those we already know at compile time that the size is ok.
  */
 #define __ua_size(size)							\
-	(__builtin_constant_p(size) && (signed long) (size) > 0 ? 0 : (size))
-
-#define __access_ok(addr,size,mask)                                     \
-	(((signed long)((mask)&(addr | (addr + size) | __ua_size(size)))) >= 0)
-
-#define __access_mask ((long)(get_fs().seg))
+	((__builtin_constant_p(size) && (signed long) (size) > 0) ? 0 : (size))
 
 /*
  * access_ok: - Checks if a user space pointer is valid
@@ -73,8 +101,14 @@
  * checks that the pointer is in the user space range - after calling
  * this function, memory access functions may still return -EFAULT.
  */
+
+#define __access_mask get_fs().seg
+
+#define __access_ok(addr, size, mask)					\
+	(((signed long)((mask) & ((addr) | ((addr) + (size)) | __ua_size(size)))) == 0)
+
 #define access_ok(type, addr, size)					\
-	likely(__access_ok((unsigned long)(addr), (size), __access_mask))
+	likely(__access_ok((unsigned long)(addr), (size),__access_mask))
 
 /*
  * verify_area: - Obsolete, use access_ok()
@@ -190,89 +224,87 @@ struct __large_struct { unsigned long bu
  * for 32 bit mode and old iron.
  */
 #ifdef __mips64
-#define __GET_USER_DW __get_user_asm("ld")
+#define __GET_USER_DW(__gu_err) __get_user_asm("ld", __gu_err)
 #else
-#define __GET_USER_DW __get_user_asm_ll32
+#define __GET_USER_DW(__gu_err) __get_user_asm_ll32(__gu_err)
 #endif
 
 #define __get_user_nocheck(x,ptr,size)					\
 ({									\
-	long __gu_err;							\
-	__typeof(*(ptr)) __gu_val;					\
+	long __gu_err = 0;						\
+	__typeof(*(ptr)) __gu_val = 0;					\
 	long __gu_addr;							\
-	__asm__("":"=r" (__gu_val));					\
 	__gu_addr = (long) (ptr);					\
-	__asm__("":"=r" (__gu_err));					\
 	switch (size) {							\
-		case 1: __get_user_asm("lb"); break;			\
-		case 2: __get_user_asm("lh"); break;			\
-		case 4: __get_user_asm("lw"); break;			\
-		case 8: __GET_USER_DW; break;				\
-		default: __get_user_unknown(); break;			\
-	} x = (__typeof__(*(ptr))) __gu_val;				\
+	case 1: __get_user_asm("lb", __gu_err); break;			\
+	case 2: __get_user_asm("lh", __gu_err); break;			\
+	case 4: __get_user_asm("lw", __gu_err); break;			\
+	case 8: __GET_USER_DW(__gu_err); break;				\
+	default: __get_user_unknown(); break;				\
+	}								\
+	 x = (__typeof__(*(ptr))) __gu_val;				\
 	__gu_err;							\
 })
 
 #define __get_user_check(x,ptr,size)					\
 ({									\
+	__typeof__(*(ptr)) __gu_val = 0;				\
+	long __gu_addr = (long) (ptr);					\
 	long __gu_err;							\
-	__typeof__(*(ptr)) __gu_val;					\
-	long __gu_addr;							\
-	__asm__("":"=r" (__gu_val));					\
-	__gu_addr = (long) (ptr);					\
-	__asm__("":"=r" (__gu_err));					\
-	if (access_ok(VERIFY_READ, __gu_addr, size)) {			\
+									\
+	__gu_err = verify_area(VERIFY_READ, (void *) __gu_addr, size);	\
+									\
+	if (likely(!__gu_err)) {					\
 		switch (size) {						\
-		case 1: __get_user_asm("lb"); break;			\
-		case 2: __get_user_asm("lh"); break;			\
-		case 4: __get_user_asm("lw"); break;			\
-		case 8: __GET_USER_DW; break;				\
+		case 1: __get_user_asm("lb", __gu_err); break;		\
+		case 2: __get_user_asm("lh", __gu_err); break;		\
+		case 4: __get_user_asm("lw", __gu_err); break;		\
+		case 8: __GET_USER_DW(__gu_err); break;			\
 		default: __get_user_unknown(); break;			\
 		}							\
-	} x = (__typeof__(*(ptr))) __gu_val;				\
-	__gu_err;							\
+	}								\
+	x = (__typeof__(*(ptr))) __gu_val;				\
+	 __gu_err;							\
 })
 
-#define __get_user_asm(insn)						\
+#define __get_user_asm(insn,__gu_err)					\
 ({									\
 	__asm__ __volatile__(						\
-	"1:\t" insn "\t%1,%2\n\t"					\
-	"move\t%0,$0\n"							\
-	"2:\n\t"							\
-	".section\t.fixup,\"ax\"\n"					\
-	"3:\tli\t%0,%3\n\t"						\
-	"move\t%1,$0\n\t"						\
-	"j\t2b\n\t"							\
-	".previous\n\t"							\
-	".section\t__ex_table,\"a\"\n\t"				\
-	".word\t1b,3b\n\t"						\
-	".previous"							\
-	:"=r" (__gu_err), "=r" (__gu_val)				\
-	:"o" (__m(__gu_addr)), "i" (-EFAULT));				\
+	"1:	" insn "	%1, %3				\n"	\
+	"2:							\n"	\
+	"	.section .fixup,\"ax\"				\n"	\
+	"3:	li	%0, %4					\n"	\
+	"	j	2b					\n"	\
+	"	.previous					\n"	\
+	"	.section __ex_table,\"a\"			\n"	\
+	"	"__UA_ADDR "\t1b, 3b				\n"	\
+	"	.previous					\n"	\
+	: "=r" (__gu_err), "=r" (__gu_val)				\
+	: "0" (__gu_err), "o" (__m(__gu_addr)), "i" (-EFAULT));		\
 })
 
 /*
  * Get a long long 64 using 32 bit registers.
  */
-#define __get_user_asm_ll32						\
+#define __get_user_asm_ll32(__gu_err)					\
 ({									\
-__asm__ __volatile__(							\
-	"1:\tlw\t%1,%2\n"						\
-	"2:\tlw\t%D1,%3\n\t"						\
-	"move\t%0,$0\n"							\
-	"3:\t.section\t.fixup,\"ax\"\n"					\
-	"4:\tli\t%0,%4\n\t"						\
-	"move\t%1,$0\n\t"						\
-	"move\t%D1,$0\n\t"						\
-	"j\t3b\n\t"							\
-	".previous\n\t"							\
-	".section\t__ex_table,\"a\"\n\t"				\
-	".word\t1b,4b\n\t"						\
-	".word\t2b,4b\n\t"						\
-	".previous"							\
-	:"=r" (__gu_err), "=&r" (__gu_val)				\
-	:"o" (__m(__gu_addr)), "o" (__m(__gu_addr + 4)),		\
-	 "i" (-EFAULT));						\
+	__asm__ __volatile__(						\
+	"1:	lw	%1, %3					\n"	\
+	"2:	lw	%D1, %4					\n"	\
+	"	move	%0, $0					\n"	\
+	"3:	.section	.fixup,\"ax\"			\n"	\
+	"4:	li	%0, %5					\n"	\
+	"	move	%1, $0					\n"	\
+	"	move	%D1, $0					\n"	\
+	"	j	3b					\n"	\
+	"	.previous					\n"	\
+	"	.section	__ex_table,\"a\"		\n"	\
+	"	" __UA_ADDR "	1b, 4b				\n"	\
+	"	" __UA_ADDR "	2b, 4b				\n"	\
+	"	.previous					\n"	\
+	: "=r" (__gu_err), "=&r" (__gu_val)				\
+	: "0" (__gu_err), "o" (__m(__gu_addr)),				\
+	  "o" (__m(__gu_addr + 4)), "i" (-EFAULT));			\
 })
 
 extern void __get_user_unknown(void);
@@ -282,84 +314,82 @@ extern void __get_user_unknown(void);
  * for 32 bit mode and old iron.
  */
 #ifdef __mips64
-#define __PUT_USER_DW __put_user_asm("sd")
+#define __PUT_USER_DW(__pu_val) __put_user_asm("sd", __pu_val)
 #else
-#define __PUT_USER_DW __put_user_asm_ll32
+#define __PUT_USER_DW(__pu_val) __put_user_asm_ll32(__pu_val)
 #endif
 
 #define __put_user_nocheck(x,ptr,size)					\
 ({									\
-	long __pu_err;							\
+	long __pu_err = 0;						\
 	__typeof__(*(ptr)) __pu_val;					\
 	long __pu_addr;							\
 	__pu_val = (x);							\
 	__pu_addr = (long) (ptr);					\
-	__asm__("":"=r" (__pu_err));					\
 	switch (size) {							\
-		case 1: __put_user_asm("sb"); break;			\
-		case 2: __put_user_asm("sh"); break;			\
-		case 4: __put_user_asm("sw"); break;			\
-		case 8: __PUT_USER_DW; break;				\
-		default: __put_user_unknown(); break;			\
+	case 1: __put_user_asm("sb", __pu_val); break;			\
+	case 2: __put_user_asm("sh", __pu_val); break;			\
+	case 4: __put_user_asm("sw", __pu_val); break;			\
+	case 8: __PUT_USER_DW(__pu_val); break;				\
+	default: __put_user_unknown(); break;				\
 	}								\
 	__pu_err;							\
 })
 
 #define __put_user_check(x,ptr,size)					\
 ({									\
+	__typeof__(*(ptr)) __pu_val = (x);				\
+	long __pu_addr = (long) (ptr);					\
 	long __pu_err;							\
-	__typeof__(*(ptr)) __pu_val;					\
-	long __pu_addr;							\
-	__pu_val = (x);							\
-	__pu_addr = (long) (ptr);					\
-	__asm__("":"=r" (__pu_err));					\
-	if (access_ok(VERIFY_WRITE, __pu_addr, size)) {			\
+									\
+	__pu_err = verify_area(VERIFY_WRITE, (void *) __pu_addr, size);	\
+									\
+	if (likely(!__pu_err)) {					\
 		switch (size) {						\
-		case 1: __put_user_asm("sb"); break;			\
-		case 2: __put_user_asm("sh"); break;			\
-		case 4: __put_user_asm("sw"); break;			\
-		case 8: __PUT_USER_DW; break;				\
+		case 1: __put_user_asm("sb", __pu_val); break;		\
+		case 2: __put_user_asm("sh", __pu_val); break;		\
+		case 4: __put_user_asm("sw", __pu_val); break;		\
+		case 8: __PUT_USER_DW(__pu_val); break;			\
 		default: __put_user_unknown(); break;			\
 		}							\
 	}								\
 	__pu_err;							\
 })
 
-#define __put_user_asm(insn)						\
+#define __put_user_asm(insn, __pu_val)					\
 ({									\
 	__asm__ __volatile__(						\
-	"1:\t" insn "\t%z1, %2\t\t\t# __put_user_asm\n\t"		\
-	"move\t%0, $0\n"						\
-	"2:\n\t"							\
-	".section\t.fixup,\"ax\"\n"					\
-	"3:\tli\t%0, %3\n\t"						\
-	"j\t2b\n\t"							\
-	".previous\n\t"							\
-	".section\t__ex_table,\"a\"\n\t"				\
-	".word\t1b, 3b\n\t"						\
-	".previous"							\
-	:"=r" (__pu_err)						\
-	:"Jr" (__pu_val), "o" (__m(__pu_addr)), "i" (-EFAULT));		\
-})
-
-#define __put_user_asm_ll32						\
-({									\
-__asm__ __volatile__(							\
-	"1:\tsw\t%1, %2\t\t\t# __put_user_asm_ll32\n\t"			\
-	"2:\tsw\t%D1, %3\n"						\
-	"move\t%0, $0\n"						\
-	"3:\n\t"							\
-	".section\t.fixup,\"ax\"\n"					\
-	"4:\tli\t%0, %4\n\t"						\
-	"j\t3b\n\t"							\
-	".previous\n\t"							\
-	".section\t__ex_table,\"a\"\n\t"				\
-	".word\t1b,4b\n\t"						\
-	".word\t2b,4b\n\t"						\
-	".previous"							\
-	:"=r" (__pu_err)						\
-	:"r" (__pu_val), "o" (__m(__pu_addr)), "o" (__m(__pu_addr + 4)),\
-	 "i" (-EFAULT));						\
+	"1:	" insn "	%z2, %3		# __put_user_asm\n"	\
+	"2:							\n"	\
+	"	.section	.fixup,\"ax\"			\n"	\
+	"3:	li	%0, %4					\n"	\
+	"	j	2b					\n"	\
+	"	.previous					\n"	\
+	"	.section	__ex_table,\"a\"		\n"	\
+	"	" __UA_ADDR "	1b, 3b				\n"	\
+	"	.previous					\n"	\
+	: "=r" (__pu_err)						\
+	: "0" (__pu_err), "Jr" (__pu_val), "o" (__m(__pu_addr)),	\
+	  "i" (-EFAULT));						\
+})
+
+#define __put_user_asm_ll32(__pu_val)					\
+({									\
+	__asm__ __volatile__(						\
+	"1:	sw	%2, %3		# __put_user_asm_ll32	\n"	\
+	"2:	sw	%D2, %4					\n"	\
+	"3:							\n"	\
+	"	.section	.fixup,\"ax\"			\n"	\
+	"4:	li	%0, %5					\n"	\
+	"	j	3b					\n"	\
+	"	.previous					\n"	\
+	"	.section	__ex_table,\"a\"		\n"	\
+	"	" __UA_ADDR "	1b, 4b				\n"	\
+	"	" __UA_ADDR "	2b, 4b				\n"	\
+	"	.previous"						\
+	: "=r" (__pu_err)						\
+	: "0" (__pu_err), "r" (__pu_val), "o" (__m(__pu_addr)),		\
+	  "o" (__m(__pu_addr + 4)), "i" (-EFAULT));			\
 })
 
 extern void __put_user_unknown(void);
@@ -371,7 +401,7 @@ extern void __put_user_unknown(void);
 #ifdef MODULE
 #define __MODULE_JAL(destination)					\
 	".set\tnoat\n\t"						\
-	"la\t$1, " #destination "\n\t"					\
+	__UA_LA "\t$1, " #destination "\n\t" 				\
 	"jalr\t$1\n\t"							\
 	".set\tat\n\t"
 #else
@@ -426,6 +456,9 @@ extern size_t __copy_user(void *__to, co
 	__cu_len;							\
 })
 
+#define __copy_to_user_inatomic __copy_to_user
+#define __copy_from_user_inatomic __copy_from_user
+
 /*
  * copy_to_user: - Copy a block of data into user space.
  * @to:   Destination address, in user space.
@@ -467,9 +500,9 @@ extern size_t __copy_user(void *__to, co
 	".set\tnoreorder\n\t"						\
 	__MODULE_JAL(__copy_user)					\
 	".set\tnoat\n\t"						\
-	"addu\t$1, %1, %2\n\t"						\
+	__UA_ADDU "\t$1, %1, %2\n\t"					\
 	".set\tat\n\t"							\
-	".set\treorder\n\t"						\
+	".set\treorder"							\
 	: "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r)	\
 	:								\
 	: "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31",		\
@@ -562,7 +595,7 @@ __clear_user(void *addr, __kernel_size_t
 		"move\t%0, $6"
 		: "=r" (res)
 		: "r" (addr), "r" (size)
-		: "$4", "$5", "$6", "$8", "$9", "$31");
+		: "$4", "$5", "$6", __UA_t0, __UA_t1, "$31");
 
 	return res;
 }
@@ -610,7 +643,7 @@ __strncpy_from_user(char *__to, const ch
 		"move\t%0, $2"
 		: "=r" (res)
 		: "r" (__to), "r" (__from), "r" (__len)
-		: "$2", "$3", "$4", "$5", "$6", "$8", "$31", "memory");
+		: "$2", "$3", "$4", "$5", "$6", __UA_t0, "$31", "memory");
 
 	return res;
 }
@@ -646,7 +679,7 @@ strncpy_from_user(char *__to, const char
 		"move\t%0, $2"
 		: "=r" (res)
 		: "r" (__to), "r" (__from), "r" (__len)
-		: "$2", "$3", "$4", "$5", "$6", "$8", "$31", "memory");
+		: "$2", "$3", "$4", "$5", "$6", __UA_t0, "$31", "memory");
 
 	return res;
 }
@@ -662,7 +695,7 @@ static inline long __strlen_user(const c
 		"move\t%0, $2"
 		: "=r" (res)
 		: "r" (s)
-		: "$2", "$4", "$8", "$31");
+		: "$2", "$4", __UA_t0, "$31");
 
 	return res;
 }
@@ -691,7 +724,24 @@ static inline long strlen_user(const cha
 		"move\t%0, $2"
 		: "=r" (res)
 		: "r" (s)
-		: "$2", "$4", "$8", "$31");
+		: "$2", "$4", __UA_t0, "$31");
+
+	return res;
+}
+
+/* Returns: 0 if bad, string length+1 (memory size) of string if ok */
+static inline long __strnlen_user(const char *s, long n)
+{
+	long res;
+
+	__asm__ __volatile__(
+		"move\t$4, %1\n\t"
+		"move\t$5, %2\n\t"
+		__MODULE_JAL(__strnlen_user_nocheck_asm)
+		"move\t%0, $2"
+		: "=r" (res)
+		: "r" (s), "r" (n)
+		: "$2", "$4", "$5", __UA_t0, "$31");
 
 	return res;
 }
@@ -699,13 +749,16 @@ static inline long strlen_user(const cha
 /*
  * strlen_user: - Get the size of a string in user space.
  * @str: The string to measure.
- * @n:   The maximum valid length
+ *
+ * Context: User context only.  This function may sleep.
  *
  * Get the size of a NUL-terminated string in user space.
  *
  * Returns the size of the string INCLUDING the terminating NUL.
  * On exception, returns 0.
- * If the string is too long, returns a value greater than @n.
+ *
+ * If there is a limit on the length of a valid string, you may wish to
+ * consider using strnlen_user() instead.
  */
 static inline long strnlen_user(const char *s, long n)
 {
@@ -718,7 +771,7 @@ static inline long strnlen_user(const ch
 		"move\t%0, $2"
 		: "=r" (res)
 		: "r" (s), "r" (n)
-		: "$2", "$4", "$5", "$8", "$31");
+		: "$2", "$4", "$5", __UA_t0, "$31");
 
 	return res;
 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/unaligned.h linux-2.4.29-pre3/include/asm-mips/unaligned.h
--- linux-2.4.28/include/asm-mips/unaligned.h	2002-11-28 23:53:15.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/unaligned.h	2004-12-22 16:07:37.472479872 +0000
@@ -3,157 +3,142 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 1999, 2000 by Ralf Baechle
- * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+ * Copyright (C) 1996, 1999, 2000, 2001, 2003 by Ralf Baechle
+ * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc.
  */
 #ifndef _ASM_UNALIGNED_H
 #define _ASM_UNALIGNED_H
 
-extern void __get_unaligned_bad_length(void);
-extern void __put_unaligned_bad_length(void);
+#include <linux/types.h>
 
 /*
- * Load double unaligned.
+ * get_unaligned - get value from possibly mis-aligned location
+ * @ptr: pointer to value
+ *
+ * This macro should be used for accessing values larger in size than
+ * single bytes at locations that are expected to be improperly aligned,
+ * e.g. retrieving a u16 value from a location not u16-aligned.
  *
- * This could have been implemented in plain C like IA64 but egcs 1.0.3a
- * inflates this to 23 instructions ...
+ * Note that unaligned accesses can be very expensive on some architectures.
  */
-static inline unsigned long long __ldq_u(const unsigned long long * __addr)
-{
-	unsigned long long __res;
+#define get_unaligned(ptr) \
+	((__typeof__(*(ptr)))__get_unaligned((ptr), sizeof(*(ptr))))
 
-	__asm__("ulw\t%0, %1\n\t"
-		"ulw\t%D0, 4+%1"
-		: "=&r" (__res)
-		: "m" (*__addr));
-
-	return __res;
-}
+/*
+ * put_unaligned - put value to a possibly mis-aligned location
+ * @val: value to place
+ * @ptr: pointer to location
+ *
+ * This macro should be used for placing values larger in size than
+ * single bytes at locations that are expected to be improperly aligned,
+ * e.g. writing a u16 value to a location not u16-aligned.
+ *
+ * Note that unaligned accesses can be very expensive on some architectures.
+ */
+#define put_unaligned(x,ptr) \
+	__put_unaligned((__u64)(x), (ptr), sizeof(*(ptr)))
 
 /*
- * Load word unaligned.
+ * This is a silly but good way to make sure that
+ * the get/put functions are indeed always optimized,
+ * and that we use the correct sizes.
  */
-static inline unsigned long __ldl_u(const unsigned int * __addr)
-{
-	unsigned long __res;
+extern void bad_unaligned_access_length(void);
 
-	__asm__("ulw\t%0,%1"
-		: "=&r" (__res)
-		: "m" (*__addr));
+/*
+ * EGCS 1.1 knows about arbitrary unaligned loads.  Define some
+ * packed structures to talk about such things with.
+ */
 
-	return __res;
-}
+struct __una_u64 { __u64 x __attribute__((packed)); };
+struct __una_u32 { __u32 x __attribute__((packed)); };
+struct __una_u16 { __u16 x __attribute__((packed)); };
 
 /*
- * Load halfword unaligned.
+ * Elemental unaligned loads
  */
-static inline unsigned long __ldw_u(const unsigned short * __addr)
+
+static inline __u64 __uldq(const __u64 * r11)
 {
-	unsigned long __res;
+	const struct __una_u64 *ptr = (const struct __una_u64 *) r11;
+	return ptr->x;
+}
 
-	__asm__("ulh\t%0,%1"
-		: "=&r" (__res)
-		: "m" (*__addr));
+static inline __u32 __uldl(const __u32 * r11)
+{
+	const struct __una_u32 *ptr = (const struct __una_u32 *) r11;
+	return ptr->x;
+}
 
-	return __res;
+static inline __u16 __uldw(const __u16 * r11)
+{
+	const struct __una_u16 *ptr = (const struct __una_u16 *) r11;
+	return ptr->x;
 }
 
 /*
- * Store doubleword ununaligned.
+ * Elemental unaligned stores
  */
-static inline void __stq_u(unsigned long __val, unsigned long long * __addr)
+
+static inline void __ustq(__u64 r5, __u64 * r11)
 {
-	__asm__("usw\t%1, %0\n\t"
-		"usw\t%D1, 4+%0"
-		: "=m" (*__addr)
-		: "r" (__val));
+	struct __una_u64 *ptr = (struct __una_u64 *) r11;
+	ptr->x = r5;
 }
 
-/*
- * Store long ununaligned.
- */
-static inline void __stl_u(unsigned long __val, unsigned int * __addr)
+static inline void __ustl(__u32 r5, __u32 * r11)
 {
-	__asm__("usw\t%1, %0"
-		: "=m" (*__addr)
-		: "r" (__val));
+	struct __una_u32 *ptr = (struct __una_u32 *) r11;
+	ptr->x = r5;
 }
 
-/*
- * Store word ununaligned.
- */
-static inline void __stw_u(unsigned long __val, unsigned short * __addr)
+static inline void __ustw(__u16 r5, __u16 * r11)
 {
-	__asm__("ush\t%1, %0"
-		: "=m" (*__addr)
-		: "r" (__val));
+	struct __una_u16 *ptr = (struct __una_u16 *) r11;
+	ptr->x = r5;
 }
 
-/*
- * get_unaligned - get value from possibly mis-aligned location
- * @ptr: pointer to value
- *
- * This macro should be used for accessing values larger in size than
- * single bytes at locations that are expected to be improperly aligned,
- * e.g. retrieving a u16 value from a location not u16-aligned.
- *
- * Note that unaligned accesses can be very expensive on some architectures.
- */
-#define get_unaligned(ptr)						\
-({									\
-	__typeof__(*(ptr)) __val;					\
-									\
-	switch (sizeof(*(ptr))) {					\
-	case 1:								\
-		__val = *(const unsigned char *)ptr;			\
-		break;							\
-	case 2:								\
-		__val = __ldw_u((const unsigned short *)ptr);		\
-		break;							\
-	case 4:								\
-		__val = __ldl_u((const unsigned int *)ptr);		\
-		break;							\
-	case 8:								\
-		__val = __ldq_u((const unsigned long long *)ptr);	\
-		break;							\
-	default:							\
-		__get_unaligned_bad_length();				\
-		break;							\
-	}								\
-									\
-	__val;								\
-})
+static inline __u64 __get_unaligned(const void *ptr, size_t size)
+{
+	__u64 val;
 
-/*
- * put_unaligned - put value to a possibly mis-aligned location
- * @val: value to place
- * @ptr: pointer to location
- *
- * This macro should be used for placing values larger in size than
- * single bytes at locations that are expected to be improperly aligned,
- * e.g. writing a u16 value to a location not u16-aligned.
- *
- * Note that unaligned accesses can be very expensive on some architectures.
- */
-#define put_unaligned(val,ptr)						\
-do {									\
-	switch (sizeof(*(ptr))) {					\
-	case 1:								\
-		*(unsigned char *)(ptr) = (val);			\
-		break;							\
-	case 2:								\
-		__stw_u(val, (unsigned short *)(ptr));			\
-		break;							\
-	case 4:								\
-		__stl_u(val, (unsigned int *)(ptr));			\
-		break;							\
-	case 8:								\
-		__stq_u(val, (unsigned long long *)(ptr));		\
-		break;							\
-	default:							\
-		__put_unaligned_bad_length();				\
-		break;							\
-	}								\
-} while(0)
+	switch (size) {
+	case 1:
+		val = *(const __u8 *)ptr;
+		break;
+	case 2:
+		val = __uldw((const __u16 *)ptr);
+		break;
+	case 4:
+		val = __uldl((const __u32 *)ptr);
+		break;
+	case 8:
+		val = __uldq((const __u64 *)ptr);
+		break;
+	default:
+		bad_unaligned_access_length();
+	}
+	return val;
+}
+
+static inline void __put_unaligned(__u64 val, void *ptr, size_t size)
+{
+	switch (size) {
+	      case 1:
+		*(__u8 *)ptr = (val);
+	        break;
+	      case 2:
+		__ustw(val, (__u16 *)ptr);
+		break;
+	      case 4:
+		__ustl(val, (__u32 *)ptr);
+		break;
+	      case 8:
+		__ustq(val, (__u64 *)ptr);
+		break;
+	      default:
+	    	bad_unaligned_access_length();
+	}
+}
 
 #endif /* _ASM_UNALIGNED_H */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/unistd.h linux-2.4.29-pre3/include/asm-mips/unistd.h
--- linux-2.4.28/include/asm-mips/unistd.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/unistd.h	2004-12-22 16:05:32.000000000 +0000
@@ -491,7 +491,7 @@
 #define __NR_semtimedop			(__NR_Linux + 214)
 
 /*
- * Offset of the last Linux flavoured syscall
+ * Offset of the last Linux 64-bit flavoured syscall
  */
 #define __NR_Linux_syscalls		214
 
@@ -730,7 +730,7 @@
 /*
  * Offset of the last N32 flavoured syscall
  */
-#define __NR_N32_Linux_syscalls		219
+#define __NR_Linux_syscalls		219
 
 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
 
@@ -754,7 +754,8 @@ type name(void) \
 	".set\treorder" \
 	: "=&r" (__v0), "=r" (__a3) \
 	: "i" (__NR_##name) \
-	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
+	  "memory"); \
 	\
 	if (__a3 == 0) \
 		return (type) __v0; \
@@ -781,7 +782,8 @@ type name(atype a) \
 	".set\treorder" \
 	: "=&r" (__v0), "=r" (__a3) \
 	: "r" (__a0), "i" (__NR_##name) \
-	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
+	  "memory"); \
 	\
 	if (__a3 == 0) \
 		return (type) __v0; \
@@ -805,7 +807,8 @@ type name(atype a, btype b) \
 	".set\treorder" \
 	: "=&r" (__v0), "=r" (__a3) \
 	: "r" (__a0), "r" (__a1), "i" (__NR_##name) \
-	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
+	  "memory"); \
 	\
 	if (__a3 == 0) \
 		return (type) __v0; \
@@ -830,7 +833,8 @@ type name(atype a, btype b, ctype c) \
 	".set\treorder" \
 	: "=&r" (__v0), "=r" (__a3) \
 	: "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name) \
-	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
+	  "memory"); \
 	\
 	if (__a3 == 0) \
 		return (type) __v0; \
@@ -855,7 +859,8 @@ type name(atype a, btype b, ctype c, dty
 	".set\treorder" \
 	: "=&r" (__v0), "+r" (__a3) \
 	: "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name) \
-	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
+	  "memory"); \
 	\
 	if (__a3 == 0) \
 		return (type) __v0; \
@@ -863,7 +868,7 @@ type name(atype a, btype b, ctype c, dty
 	return -1; \
 }
 
-#if (_MIPS_SIM == _MIPS_SIM_ABIN32)
+#if (_MIPS_SIM == _MIPS_SIM_ABI32)
 
 /*
  * Using those means your brain needs more than an oil change ;-)
@@ -891,7 +896,8 @@ type name(atype a, btype b, ctype c, dty
 	: "=&r" (__v0), "+r" (__a3) \
 	: "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name), \
 	  "m" ((unsigned long)e) \
-	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
+	  "memory"); \
 	\
 	if (__a3 == 0) \
 		return (type) __v0; \
@@ -923,7 +929,8 @@ type name(atype a, btype b, ctype c, dty
 	: "=&r" (__v0), "+r" (__a3) \
 	: "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name), \
 	  "m" ((unsigned long)e), "m" ((unsigned long)f) \
-	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
+	  "memory"); \
 	\
 	if (__a3 == 0) \
 		return (type) __v0; \
@@ -931,9 +938,9 @@ type name(atype a, btype b, ctype c, dty
 	return -1; \
 }
 
-#endif /* (_MIPS_SIM == _MIPS_SIM_ABIN32) */
+#endif /* (_MIPS_SIM == _MIPS_SIM_ABI32) */
 
-#if (_MIPS_SIM == _MIPS_SIM_NABIN32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
+#if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
 
 #define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
 type name (atype a,btype b,ctype c,dtype d,etype e) \
@@ -951,9 +958,10 @@ type name (atype a,btype b,ctype c,dtype
 	"syscall\n\t" \
 	"move\t%0, $2\n\t" \
 	".set\treorder" \
-	: "=&r" (__v0), "+r" (__a3), "+r" (__a4) \
-	: "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name) \
-	: "$2","$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	: "=&r" (__v0), "+r" (__a3) \
+	: "r" (__a0), "r" (__a1), "r" (__a2), "r" (__a4), "i" (__NR_##name) \
+	: "$2", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
+	  "memory"); \
 	\
 	if (__a3 == 0) \
 		return (type) __v0; \
@@ -981,7 +989,8 @@ type name (atype a,btype b,ctype c,dtype
 	: "=&r" (__v0), "+r" (__a3) \
 	: "r" (__a0), "r" (__a1), "r" (__a2), "r" (__a4), "r" (__a5), \
 	  "i" (__NR_##name) \
-	: "$2","$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	: "$2", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
+	  "memory"); \
 	\
 	if (__a3 == 0) \
 		return (type) __v0; \
@@ -989,7 +998,7 @@ type name (atype a,btype b,ctype c,dtype
 	return -1; \
 }
 
-#endif /* (_MIPS_SIM == _MIPS_SIM_NABIN32) || (_MIPS_SIM == _MIPS_SIM_ABI64) */
+#endif /* (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) */
 
 #ifdef __KERNEL_SYSCALLS__
 
@@ -1015,7 +1024,7 @@ static inline _syscall1(int,dup,int,fd)
 static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
 static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
 static inline _syscall1(int,close,int,fd)
-static inline _syscall1(int,_exit,int,exitcode)
+static inline _syscall1(void,_exit,int,exitcode)
 static inline _syscall4(pid_t,wait4,pid_t,pid,int *,stat_addr,int,options,struct rusage *,ru)
 static inline _syscall1(int,delete_module,const char *,name)
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/vr41xx/tb0229.h linux-2.4.29-pre3/include/asm-mips/vr41xx/tb0229.h
--- linux-2.4.28/include/asm-mips/vr41xx/tb0229.h	2003-08-25 11:44:44.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/vr41xx/tb0229.h	2004-12-22 16:05:49.009968680 +0000
@@ -68,6 +68,6 @@
 
 #define TB0219_RESET_REGS		KSEG1ADDR(0x0a00000e)
 
-extern void tanbac_tb0229_restart(char *command);
+extern void tanbac_tb0219_restart(char *command);
 
 #endif /* __TANBAC_TB0229_H */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/vr41xx/vr41xx.h linux-2.4.29-pre3/include/asm-mips/vr41xx/vr41xx.h
--- linux-2.4.28/include/asm-mips/vr41xx/vr41xx.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/vr41xx/vr41xx.h	2004-12-22 16:05:32.000000000 +0000
@@ -53,8 +53,6 @@ extern unsigned long vr41xx_get_tclock_f
  * Clock Mask Unit
  */
 extern void vr41xx_cmu_init(void);
-extern void vr41xx_clock_supply(unsigned int clock);
-extern void vr41xx_clock_mask(unsigned int clock);
 
 enum {
 	PIU_CLOCK,
@@ -72,6 +70,9 @@ enum {
 	ETHER1_CLOCK
 };
 
+extern void vr41xx_supply_clock(unsigned int clock);
+extern void vr41xx_mask_clock(unsigned int clock);
+
 /*
  * Interrupt Control Unit
  */
@@ -134,6 +135,11 @@ extern int vr41xx_set_intassign(unsigned
 extern int vr41xx_cascade_irq(unsigned int irq, int (*get_irq_number)(int irq));
 
 /*
+ * Power Management Unit
+ */
+extern void vr41xx_pmu_init(void);
+
+/*
  * RTC
  */
 extern void vr41xx_set_rtclong1_cycle(uint32_t cycles);
@@ -208,9 +214,9 @@ extern void vr41xx_dsiu_init(void);
  * PCI Control Unit
  */
 struct vr41xx_pci_address_space {
-	u32 internal_base;
-	u32 address_mask;
-	u32 pci_base;
+	uint32_t internal_base;
+	uint32_t address_mask;
+	uint32_t pci_base;
 };
 
 struct vr41xx_pci_address_map {
@@ -221,16 +227,14 @@ struct vr41xx_pci_address_map {
 
 extern void vr41xx_pciu_init(struct vr41xx_pci_address_map *map);
 
+extern struct pci_ops vr41xx_pci_ops;
+
 /*
  * MISC
  */
 extern void vr41xx_time_init(void);
 extern void vr41xx_timer_setup(struct irqaction *irq);
 
-extern void vr41xx_restart(char *command);
-extern void vr41xx_halt(void);
-extern void vr41xx_power_off(void);
-
 #if defined(CONFIG_IDE) || defined(CONFIG_IDE_MODULE)
 extern struct ide_ops vr41xx_ide_ops;
 #endif
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/vr41xx/vrc4173.h linux-2.4.29-pre3/include/asm-mips/vr41xx/vrc4173.h
--- linux-2.4.28/include/asm-mips/vr41xx/vrc4173.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/vr41xx/vrc4173.h	2004-12-22 16:06:34.159104968 +0000
@@ -72,21 +72,23 @@ extern unsigned long vrc4173_io_offset;
 /*
  * Clock Mask Unit
  */
-#define VRC4173_PIU_CLOCK		0x0001
-#define VRC4173_KIU_CLOCK		0x0002
-#define VRC4173_AIU_CLOCK		0x0004
-#define VRC4173_PS2CH1_CLOCK		0x0008
-#define VRC4173_PS2CH2_CLOCK		0x0010
-#define VRC4173_USBU_PCI_CLOCK		0x0020
-#define VRC4173_CARDU1_PCI_CLOCK	0x0040
-#define VRC4173_CARDU2_PCI_CLOCK	0x0080
-#define VRC4173_AC97U_PCI_CLOCK		0x0100
-#define VRC4173_USBU_48MHz_CLOCK	0x0400
-#define VRC4173_EXT_48MHz_CLOCK		0x0800
-#define VRC4173_48MHz_CLOCK		0x1000
+enum {
+	VRC4173_PIU_CLOCK,
+	VRC4173_KIU_CLOCK,
+	VRC4173_AIU_CLOCK,
+	VRC4173_PS2_CH1_CLOCK,
+	VRC4173_PS2_CH2_CLOCK,
+	VRC4173_USBU_PCI_CLOCK,
+	VRC4173_CARDU1_PCI_CLOCK,
+	VRC4173_CARDU2_PCI_CLOCK,
+	VRC4173_AC97U_PCI_CLOCK,
+	VRC4173_USBU_48MHz_CLOCK,
+	VRC4173_EXT_48MHz_CLOCK,
+	VRC4173_48MHz_CLOCK,
+};
 
-extern void vrc4173_clock_supply(u16 mask);
-extern void vrc4173_clock_mask(u16 mask);
+extern void vrc4173_supply_clock(unsigned int clock);
+extern void vrc4173_mask_clock(unsigned int clock);
 
 /*
  * General-Purpose I/O Unit
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips/war.h linux-2.4.29-pre3/include/asm-mips/war.h
--- linux-2.4.28/include/asm-mips/war.h	2003-08-25 11:44:44.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips/war.h	2004-12-22 16:05:31.000000000 +0000
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2002 by Ralf Baechle
+ * Copyright (C) 2002, 2004 by Ralf Baechle
  */
 #ifndef _ASM_WAR_H
 #define _ASM_WAR_H
@@ -11,6 +11,15 @@
 #include <linux/config.h>
 
 /*
+ * Another R4600 erratum.  Due to the lack of errata information the exact
+ * technical details aren't known.  I've experimentally found that disabling
+ * interrupts during indexed I-cache flushes seems to be sufficient to deal
+ * with the issue.
+ *
+ * #define R4600_V1_INDEX_ICACHEOP_WAR 1
+ */
+
+/*
  * Pleasures of the R4600 V1.x.  Cite from the IDT R4600 V1.7 errata:
  *
  *  18. The CACHE instructions Hit_Writeback_Invalidate_D, Hit_Writeback_D,
@@ -59,6 +68,7 @@
  */
 #ifdef CONFIG_SGI_IP22
 
+#define R4600_V1_INDEX_ICACHEOP_WAR	1
 #define R4600_V1_HIT_CACHEOP_WAR	1
 #define R4600_V2_HIT_CACHEOP_WAR	1
 
@@ -159,8 +169,19 @@
 #endif
 
 /*
+ * On the RM9000 there is a problem which makes the CreateDirtyExclusive
+ * cache operation unusable on SMP systems.
+ */
+#if defined(CONFIG_MOMENCO_JAGUAR_ATX) || defined(CONFIG_PMC_YOSEMITE)
+#define  RM9000_CDEX_SMP_WAR		1
+#endif
+
+/*
  * Workarounds default to off
  */
+#ifndef R4600_V1_INDEX_ICACHEOP_WAR
+#define R4600_V1_INDEX_ICACHEOP_WAR	0
+#endif
 #ifndef R4600_V1_HIT_CACHEOP_WAR
 #define R4600_V1_HIT_CACHEOP_WAR	0
 #endif
@@ -185,5 +206,8 @@
 #ifndef TX49XX_ICACHE_INDEX_INV_WAR
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
 #endif
+#ifndef RM9000_CDEX_SMP_WAR
+#define RM9000_CDEX_SMP_WAR		0
+#endif
 
 #endif /* _ASM_WAR_H */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips64/checksum.h linux-2.4.29-pre3/include/asm-mips64/checksum.h
--- linux-2.4.28/include/asm-mips64/checksum.h	2003-08-25 11:44:44.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips64/checksum.h	2004-12-22 16:06:06.606293632 +0000
@@ -127,9 +127,6 @@ static inline unsigned short ip_fast_csu
 }
 
 /*
- * computes the checksum of the TCP/UDP pseudo-header
- * returns a 16-bit checksum, already complemented
- *
  * Cast unsigned short expressions to unsigned long explicitly
  * to avoid surprises resulting from implicit promotions to
  * signed int.  --macro
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips64/compiler.h linux-2.4.29-pre3/include/asm-mips64/compiler.h
--- linux-2.4.28/include/asm-mips64/compiler.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips64/compiler.h	2004-12-22 16:07:37.831425304 +0000
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2004  Maciej W. Rozycki
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#ifndef _ASM_COMPILER_H
+#define _ASM_COMPILER_H
+
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+#define GCC_REG_ACCUM "$0"
+#else
+#define GCC_REG_ACCUM "accum"
+#endif
+
+#endif /* _ASM_COMPILER_H */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips64/cpu.h linux-2.4.29-pre3/include/asm-mips64/cpu.h
--- linux-2.4.28/include/asm-mips64/cpu.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips64/cpu.h	2004-12-22 16:05:48.714013672 +0000
@@ -173,7 +173,8 @@
 #define CPU_VR4133		56
 #define CPU_AU1550		57
 #define CPU_24K			58
-#define CPU_LAST		58
+#define CPU_AU1200		59
+#define CPU_LAST		59
 
 /*
  * ISA Level encodings
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips64/dec/prom.h linux-2.4.29-pre3/include/asm-mips64/dec/prom.h
--- linux-2.4.28/include/asm-mips64/dec/prom.h	2003-08-25 11:44:44.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips64/dec/prom.h	2004-12-22 16:06:18.907423576 +0000
@@ -164,4 +164,7 @@ extern void prom_meminit(u32);
 extern void prom_identify_arch(u32);
 extern void prom_init_cmdline(s32, s32 *, u32);
 
+extern void register_prom_console(void);
+extern void unregister_prom_console(void);
+
 #endif /* __ASM_DEC_PROM_H */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips64/dec/serial.h linux-2.4.29-pre3/include/asm-mips64/dec/serial.h
--- linux-2.4.28/include/asm-mips64/dec/serial.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips64/dec/serial.h	2004-12-22 16:06:57.353578872 +0000
@@ -0,0 +1,36 @@
+/*
+ *	include/asm-mips/dec/serial.h
+ *
+ *	Definitions common to all DECstation serial devices.
+ *
+ *	Copyright (C) 2004  Maciej W. Rozycki
+ *
+ *	Based on bits extracted from drivers/tc/zs.h for which
+ *	the following copyrights apply:
+ *
+ *	Copyright (C) 1995  David S. Miller (davem@caip.rutgers.edu)
+ *	Copyright (C) 1996  Paul Mackerras (Paul.Mackerras@cs.anu.edu.au)
+ *	Copyright (C)       Harald Koerfgen
+ *
+ *	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 __ASM_MIPS_DEC_SERIAL_H
+#define __ASM_MIPS_DEC_SERIAL_H
+
+struct dec_serial_hook {
+	int (*init_channel)(void *handle);
+	void (*init_info)(void *handle);
+	void (*rx_char)(unsigned char ch, unsigned char fl);
+	int (*poll_rx_char)(void *handle);
+	int (*poll_tx_char)(void *handle, unsigned char ch);
+	unsigned int cflags;
+};
+
+extern int register_dec_serial_hook(unsigned int channel,
+				    struct dec_serial_hook *hook);
+extern int unregister_dec_serial_hook(unsigned int channel);
+
+#endif /* __ASM_MIPS_DEC_SERIAL_H */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips64/delay.h linux-2.4.29-pre3/include/asm-mips64/delay.h
--- linux-2.4.28/include/asm-mips64/delay.h	2003-08-25 11:44:44.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips64/delay.h	2004-12-22 16:07:39.888112640 +0000
@@ -13,6 +13,8 @@
 #include <linux/config.h>
 #include <linux/param.h>
 
+#include <asm/compiler.h>
+
 extern unsigned long loops_per_jiffy;
 
 static __inline__ void
@@ -53,8 +55,9 @@ static inline void __udelay(unsigned lon
 	usecs *= (0x8000000000000000UL / (500000 / HZ));
 #endif
 	__asm__("dmultu\t%2,%3"
-		:"=h" (usecs), "=l" (lo)
-		:"r" (usecs),"r" (lpj));
+		: "=h" (usecs), "=l" (lo)
+		: "r" (usecs), "r" (lpj)
+		: GCC_REG_ACCUM);
 	__delay(usecs);
 }
 
@@ -74,8 +77,9 @@ static inline void __ndelay(unsigned lon
 	nsecs *= (0x8000000000000000UL / (500000000 / HZ));
 #endif
 	__asm__("dmultu\t%2,%3"
-		:"=h" (nsecs), "=l" (lo)
-		:"r" (nsecs),"r" (lpj));
+		: "=h" (nsecs), "=l" (lo)
+		: "r" (nsecs), "r" (lpj)
+		: GCC_REG_ACCUM);
 	__delay(nsecs);
 }
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips64/mipsregs.h linux-2.4.29-pre3/include/asm-mips64/mipsregs.h
--- linux-2.4.28/include/asm-mips64/mipsregs.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips64/mipsregs.h	2004-12-22 16:06:09.001929440 +0000
@@ -632,6 +632,24 @@ do {									\
 } while (0)
 
 /*
+ * On RM7000/RM9000 these are uses to access cop0 set 1 registers
+ */
+#define __read_32bit_c0_ctrl_register(source)				\
+({ int __res;								\
+	__asm__ __volatile__(						\
+		"cfc0\t%0, " #source "\n\t"				\
+		: "=r" (__res));					\
+	__res;								\
+})
+
+#define __write_32bit_c0_ctrl_register(register, value)			\
+do {									\
+	__asm__ __volatile__(						\
+		"ctc0\t%z0, " #register "\n\t"				\
+		: : "Jr" ((unsigned int)value));			\
+} while (0)
+
+/*
  * These versions are only needed for systems with more than 38 bits of
  * physical address space running the 32-bit kernel.  That's none atm :-)
  */
@@ -788,8 +806,8 @@ do {									\
 #define read_c0_xcontext()	__read_ulong_c0_register($20, 0)
 #define write_c0_xcontext(val)	__write_ulong_c0_register($20, 0, val)
 
-#define read_c0_intcontrol()	__read_32bit_c0_register($20, 1)
-#define write_c0_intcontrol(val) __write_32bit_c0_register($20, 1, val)
+#define read_c0_intcontrol()	__read_32bit_c0_ctrl_register($20)
+#define write_c0_intcontrol(val) __write_32bit_c0_ctrl_register($20, val)
 
 #define read_c0_framemask()	__read_32bit_c0_register($21, 0)
 #define write_c0_framemask(val)	__write_32bit_c0_register($21, 0, val)
@@ -879,7 +897,7 @@ static inline void tlb_write_random(void
 /*
  * Manipulate bits in a c0 register.
  */
-#define __BUILD_SET_C0(name,register)				\
+#define __BUILD_SET_C0(name)					\
 static inline unsigned int					\
 set_c0_##name(unsigned int set)					\
 {								\
@@ -917,9 +935,10 @@ change_c0_##name(unsigned int change, un
 	return res;						\
 }
 
-__BUILD_SET_C0(status,CP0_STATUS)
-__BUILD_SET_C0(cause,CP0_CAUSE)
-__BUILD_SET_C0(config,CP0_CONFIG)
+__BUILD_SET_C0(status)
+__BUILD_SET_C0(cause)
+__BUILD_SET_C0(config)
+__BUILD_SET_C0(intcontrol)
 
 #endif /* !__ASSEMBLY__ */
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips64/mmu_context.h linux-2.4.29-pre3/include/asm-mips64/mmu_context.h
--- linux-2.4.28/include/asm-mips64/mmu_context.h	2003-08-25 11:44:44.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips64/mmu_context.h	2004-12-22 16:05:40.253299896 +0000
@@ -35,9 +35,23 @@ extern unsigned long pgd_current[];
 #define cpu_asid(cpu, mm)	(cpu_context((cpu), (mm)) & ASID_MASK)
 #define asid_cache(cpu)		(cpu_data[cpu].asid_cache)
 
+#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+
+#define ASID_INC	0x40
+#define ASID_MASK	0xfc0
+
+#elif defined(CONFIG_CPU_RM9000)
+
+#define ASID_INC	0x1
+#define ASID_MASK	0xfff
+
+#else /* FIXME: not correct for R6000, R8000 */
+
 #define ASID_INC	0x1
 #define ASID_MASK	0xff
 
+#endif
+
 static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu)
 {
 }
@@ -127,7 +141,7 @@ activate_mm(struct mm_struct *prev, stru
 	write_c0_entryhi(cpu_context(cpu, next));
 	TLBMISS_HANDLER_SETUP_PGD(next->pgd);
 
-	/* mark mmu ownership change */ 
+	/* mark mmu ownership change */
 	clear_bit(cpu, &prev->cpu_vm_mask);
 	set_bit(cpu, &next->cpu_vm_mask);
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips64/param.h linux-2.4.29-pre3/include/asm-mips64/param.h
--- linux-2.4.28/include/asm-mips64/param.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips64/param.h	2004-12-22 16:06:24.909511120 +0000
@@ -20,6 +20,8 @@
 
 #include <linux/config.h>
 
+#include <asm/compiler.h>
+
 #ifdef CONFIG_DECSTATION
    /*
     * log2(HZ), change this here if you want another HZ value. This is also
@@ -36,8 +38,9 @@
    ({ unsigned long __res;			\
       unsigned long __lo;			\
 	__asm__("dmultu\t%2,%3\n\t"		\
-		:"=h" (__res), "=l" (__lo)	\
-		:"r" (a), "r" (QUOTIENT));	\
+		: "=h" (__res), "=l" (__lo)	\
+		: "r" (a), "r" (QUOTIENT)	\
+		: GCC_REG_ACCUM);		\
 	(__typeof__(a)) __res;})
 
 #else /* Not a DECstation  */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips64/prefetch.h linux-2.4.29-pre3/include/asm-mips64/prefetch.h
--- linux-2.4.28/include/asm-mips64/prefetch.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips64/prefetch.h	2004-12-22 16:05:33.051394752 +0000
@@ -21,8 +21,9 @@
  * RM7000 version 1.0 interprets all hints as Pref_Load; version 2.0 implements
  * Pref_PrepareForStore also.
  *
- * RM9000 is MIPS IV but implements prefetching like MIPS32/MIPS64;
- * it's Pref_WriteBackInvalidate is a nop.
+ * RM9000 is MIPS IV but implements prefetching like MIPS32/MIPS64; it's
+ * Pref_WriteBackInvalidate is a nop and Pref_PrepareForStore is broken in
+ * current versions due to erratum G105.
  *
  * VR7701 only implements the Load prefetch.
  *
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips64/processor.h linux-2.4.29-pre3/include/asm-mips64/processor.h
--- linux-2.4.28/include/asm-mips64/processor.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips64/processor.h	2004-12-22 16:06:44.858478416 +0000
@@ -128,6 +128,8 @@ struct cpuinfo_mips {
 #define cpu_has_dc_aliases	(cpu_data[0].dcache.flags & MIPS_CACHE_ALIASES)
 #define cpu_has_ic_fills_f_dc	(cpu_data[0].dcache.flags & MIPS_CACHE_IC_F_DC)
 #define cpu_has_64bits		1
+#define cpu_has_64bit_zero_reg	1
+#define cpu_has_64bit_gp_regs	1
 #define cpu_has_64bit_addresses	1
 #define cpu_has_subset_pcaches	(cpu_data[0].options & MIPS_CPU_SUBSET_CACHES)
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips64/sgiarcs.h linux-2.4.29-pre3/include/asm-mips64/sgiarcs.h
--- linux-2.4.28/include/asm-mips64/sgiarcs.h	2003-08-25 11:44:44.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips64/sgiarcs.h	2004-12-22 16:06:26.609252720 +0000
@@ -369,7 +369,7 @@ struct linux_smonblock {
 
 #define __arc_clobbers							\
 	"$2","$3" /* ... */, "$8","$9","$10","$11",			\
-	"$12","$13","$14","$15","$16","$24","25","$31"
+	"$12","$13","$14","$15","$16","$24","$25","$31"
 
 #define ARC_CALL0(dest)							\
 ({	long __res;							\
@@ -462,7 +462,7 @@ struct linux_smonblock {
 	long __vec = (long) romvec->dest;				\
 	__asm__ __volatile__(						\
 	"dsubu\t$29, 32\n\t"						\
-	"sw\t%6, 16($29)\n\t"						\
+	"sw\t%7, 16($29)\n\t"						\
 	"jalr\t%1\n\t"							\
 	"daddu\t$29, 32\n\t"						\
 	"move\t%0, $2"							\
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips64/siginfo.h linux-2.4.29-pre3/include/asm-mips64/siginfo.h
--- linux-2.4.28/include/asm-mips64/siginfo.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips64/siginfo.h	2004-12-22 16:07:31.206432456 +0000
@@ -3,12 +3,13 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1998, 1999, 2001, 2003 Ralf Baechle
+ * Copyright (C) 1998, 1999, 2001, 03, 04 Ralf Baechle
  * Copyright (C) 2000, 2001 Silicon Graphics, Inc.
  */
 #ifndef _ASM_SIGINFO_H
 #define _ASM_SIGINFO_H
 
+#include <linux/config.h>
 #include <linux/types.h>
 
 /* This structure matches IRIX 32/n32 ABIs for binary compatibility. */
@@ -18,26 +19,22 @@ typedef union sigval {
 	void *sival_ptr;
 } sigval_t;
 
-#ifdef __KERNEL__
-
-typedef union sigval32 {
-	int sival_int;
-	s32 sival_ptr;
-} sigval_t32;
-
-#endif /* __KERNEL__ */
-
 /* This structure matches IRIX 32/n32 ABIs for binary compatibility but
    has Linux extensions.  */
 
 #define SI_MAX_SIZE	128
+#ifdef CONFIG_MIPS32
+#define SI_PAD_SIZE	((SI_MAX_SIZE/sizeof(int)) - 3)
+#endif
+#ifdef CONFIG_MIPS64
 #define SI_PAD_SIZE	((SI_MAX_SIZE/sizeof(int)) - 4)
-#define SI_PAD_SIZE32	((SI_MAX_SIZE/sizeof(int)) - 3)
+#endif
 
 typedef struct siginfo {
 	int si_signo;
 	int si_code;
 	int si_errno;
+	int __pad0[SI_MAX_SIZE / sizeof(int) - SI_PAD_SIZE - 3];
 
 	union {
 		int _pad[SI_PAD_SIZE];
@@ -52,8 +49,8 @@ typedef struct siginfo {
 		struct {
 			pid_t _pid;		/* which child */
 			uid_t _uid;		/* sender's uid */
-			clock_t _utime;
 			int _status;		/* exit code */
+			clock_t _utime;
 			clock_t _stime;
 		} _sigchld;
 
@@ -92,68 +89,6 @@ typedef struct siginfo {
 	} _sifields;
 } siginfo_t;
 
-#ifdef __KERNEL__
-
-typedef struct siginfo32 {
-	int si_signo;
-	int si_code;
-	int si_errno;
-
-	union {
-		int _pad[SI_PAD_SIZE32];
-
-		/* kill() */
-		struct {
-			__kernel_pid_t32 _pid;	/* sender's pid */
-			__kernel_uid_t32 _uid;	/* sender's uid */
-		} _kill;
-
-		/* SIGCHLD */
-		struct {
-			__kernel_pid_t32 _pid;	/* which child */
-			__kernel_uid_t32 _uid;	/* sender's uid */
-			__kernel_clock_t32 _utime;
-			int _status;		/* exit code */
-			__kernel_clock_t32 _stime;
-		} _sigchld;
-
-		/* IRIX SIGCHLD */
-		struct {
-			__kernel_pid_t32 _pid;	/* which child */
-			__kernel_clock_t32 _utime;
-			int _status;		/* exit code */
-			__kernel_clock_t32 _stime;
-		} _irix_sigchld;
-
-		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
-		struct {
-			s32 _addr; /* faulting insn/memory ref. */
-		} _sigfault;
-
-		/* SIGPOLL, SIGXFSZ (To do ...)  */
-		struct {
-			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
-			int _fd;
-		} _sigpoll;
-
-		/* POSIX.1b timers */
-		struct {
-			unsigned int _timer1;
-			unsigned int _timer2;
-		} _timer;
-
-		/* POSIX.1b signals */
-		struct {
-			__kernel_pid_t32 _pid;	/* sender's pid */
-			__kernel_uid_t32 _uid;	/* sender's uid */
-			sigval_t32 _sigval;
-		} _rt;
-
-	} _sifields;
-} siginfo_t32;
-
-#endif /* __KERNEL__ */
-
 /*
  * How these fields are to be accessed.
  */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips64/smp.h linux-2.4.29-pre3/include/asm-mips64/smp.h
--- linux-2.4.28/include/asm-mips64/smp.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips64/smp.h	2004-12-22 16:06:16.427800536 +0000
@@ -106,7 +106,7 @@ void core_send_ipi(int cpu, unsigned int
  * Clear all undefined state in the cpu, set up sp and gp to the passed
  * values, and kick the cpu into smp_bootstrap();
  */
-void prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp);
+int prom_boot_secondary(int cpu, unsigned long sp, unsigned long gp);
 
 /*
  *  After we've done initial boot, this function is called to allow the
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips64/uaccess.h linux-2.4.29-pre3/include/asm-mips64/uaccess.h
--- linux-2.4.28/include/asm-mips64/uaccess.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips64/uaccess.h	2004-12-22 16:06:20.988107264 +0000
@@ -3,19 +3,17 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 1997, 1998, 1999, 2000, 03 by Ralf Baechle
+ * Copyright (C) 1996, 1997, 1998, 1999, 2000, 03, 04 by Ralf Baechle
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  */
 #ifndef _ASM_UACCESS_H
 #define _ASM_UACCESS_H
 
+#include <linux/config.h>
 #include <linux/compiler.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
 
-#define STR(x)  __STR(x)
-#define __STR(x)  #x
-
 /*
  * The fs value determines whether argument validity checking should be
  * performed or not.  If get_fs() == USER_DS, checking is performed, with
@@ -23,15 +21,47 @@
  *
  * For historical reasons, these macros are grossly misnamed.
  */
+#ifdef CONFIG_MIPS32
+
+#define __UA_LIMIT	0x80000000UL
+
+#define __UA_ADDR	".word"
+#define __UA_LA		"la"
+#define __UA_ADDU	"addu"
+#define __UA_t0		"$8"
+#define __UA_t1		"$9"
+
+#endif /* CONFIG_MIPS32 */
+
+#ifdef CONFIG_MIPS64
+
+#define __UA_LIMIT	(- TASK_SIZE)
+
+#define __UA_ADDR	".dword"
+#define __UA_LA		"dla"
+#define __UA_ADDU	"daddu"
+#define __UA_t0		"$12"
+#define __UA_t1		"$13"
+
+#endif /* CONFIG_MIPS64 */
+
+/*
+ * USER_DS is a bitmask that has the bits set that may not be set in a valid
+ * userspace address.  Note that we limit 32-bit userspace to 0x7fff8000 but
+ * the arithmetic we're doing only works if the limit is a power of two, so
+ * we use 0x80000000 here on 32-bit kernels.  If a process passes an invalid
+ * address in this range it's the process's problem, not ours :-)
+ */
+
 #define KERNEL_DS	((mm_segment_t) { 0UL })
-#define USER_DS		((mm_segment_t) { -TASK_SIZE })
+#define USER_DS		((mm_segment_t) { __UA_LIMIT })
 
 #define VERIFY_READ    0
 #define VERIFY_WRITE   1
 
-#define get_fs()        (current->thread.current_ds)
 #define get_ds()	(KERNEL_DS)
-#define set_fs(x)       (current->thread.current_ds=(x))
+#define get_fs()	(current->thread.current_ds)
+#define set_fs(x)	(current->thread.current_ds = (x))
 
 #define segment_eq(a,b)	((a).seg == (b).seg)
 
@@ -45,14 +75,12 @@
  *  - AND "size" doesn't have any high-bits set
  *  - AND "addr+size" doesn't have any high-bits set
  *  - OR we are in kernel mode.
+ *
+ * __ua_size() is a trick to avoid runtime checking of positive constant
+ * sizes; for those we already know at compile time that the size is ok.
  */
 #define __ua_size(size)							\
-	((__builtin_constant_p(size) && (size)) > 0 ? 0 : (size))
-
-#define __access_ok(addr, size, mask)					\
-	(((mask) & ((addr) | ((addr) + (size)) | __ua_size(size))) == 0)
-
-#define __access_mask get_fs().seg
+	((__builtin_constant_p(size) && (signed long) (size) > 0) ? 0 : (size))
 
 /*
  * access_ok: - Checks if a user space pointer is valid
@@ -73,8 +101,14 @@
  * checks that the pointer is in the user space range - after calling
  * this function, memory access functions may still return -EFAULT.
  */
+
+#define __access_mask get_fs().seg
+
+#define __access_ok(addr, size, mask)					\
+	(((signed long)((mask) & ((addr) | ((addr) + (size)) | __ua_size(size)))) == 0)
+
 #define access_ok(type, addr, size)					\
-	likely(__access_ok((unsigned long)(addr), (size), __access_mask))
+	likely(__access_ok((unsigned long)(addr), (size),__access_mask))
 
 /*
  * verify_area: - Obsolete, use access_ok()
@@ -185,117 +219,177 @@ static inline int verify_area(int type, 
 struct __large_struct { unsigned long buf[100]; };
 #define __m(x) (*(struct __large_struct *)(x))
 
+/*
+ * Yuck.  We need two variants, one for 64bit operation and one
+ * for 32 bit mode and old iron.
+ */
+#ifdef __mips64
+#define __GET_USER_DW(__gu_err) __get_user_asm("ld", __gu_err)
+#else
+#define __GET_USER_DW(__gu_err) __get_user_asm_ll32(__gu_err)
+#endif
+
 #define __get_user_nocheck(x,ptr,size)					\
 ({									\
-	long __gu_err;							\
-	__typeof(*(ptr)) __gu_val;					\
+	long __gu_err = 0;						\
+	__typeof(*(ptr)) __gu_val = 0;					\
 	long __gu_addr;							\
-	__asm__("":"=r" (__gu_val));					\
 	__gu_addr = (long) (ptr);					\
-	__asm__("":"=r" (__gu_err));					\
 	switch (size) {							\
-		case 1: __get_user_asm("lb"); break;			\
-		case 2: __get_user_asm("lh"); break;			\
-		case 4: __get_user_asm("lw"); break;			\
-		case 8: __get_user_asm("ld"); break;			\
-		default: __get_user_unknown(); break;			\
-	} x = (__typeof__(*(ptr))) __gu_val;				\
+	case 1: __get_user_asm("lb", __gu_err); break;			\
+	case 2: __get_user_asm("lh", __gu_err); break;			\
+	case 4: __get_user_asm("lw", __gu_err); break;			\
+	case 8: __GET_USER_DW(__gu_err); break;				\
+	default: __get_user_unknown(); break;				\
+	}								\
+	 x = (__typeof__(*(ptr))) __gu_val;				\
 	__gu_err;							\
 })
 
 #define __get_user_check(x,ptr,size)					\
 ({									\
+	__typeof__(*(ptr)) __gu_val = 0;				\
+	long __gu_addr = (long) (ptr);					\
 	long __gu_err;							\
-	__typeof__(*(ptr)) __gu_val;					\
-	long __gu_addr;							\
-	__asm__("":"=r" (__gu_val));					\
-	__gu_addr = (long) (ptr);					\
-	__asm__("":"=r" (__gu_err));					\
-	if (access_ok(VERIFY_READ, __gu_addr, size)) {			\
+									\
+	__gu_err = verify_area(VERIFY_READ, (void *) __gu_addr, size);	\
+									\
+	if (likely(!__gu_err)) {					\
 		switch (size) {						\
-		case 1: __get_user_asm("lb"); break;			\
-		case 2: __get_user_asm("lh"); break;			\
-		case 4: __get_user_asm("lw"); break;			\
-		case 8: __get_user_asm("ld"); break;			\
+		case 1: __get_user_asm("lb", __gu_err); break;		\
+		case 2: __get_user_asm("lh", __gu_err); break;		\
+		case 4: __get_user_asm("lw", __gu_err); break;		\
+		case 8: __GET_USER_DW(__gu_err); break;			\
 		default: __get_user_unknown(); break;			\
 		}							\
-	} x = (__typeof__(*(ptr))) __gu_val;				\
-	__gu_err;							\
+	}								\
+	x = (__typeof__(*(ptr))) __gu_val;				\
+	 __gu_err;							\
 })
 
-#define __get_user_asm(insn)						\
+#define __get_user_asm(insn,__gu_err)					\
 ({									\
 	__asm__ __volatile__(						\
-	"1:\t" insn "\t%1,%2\n\t"					\
-	"move\t%0,$0\n"							\
-	"2:\n\t"							\
-	".section\t.fixup,\"ax\"\n"					\
-	"3:\tli\t%0,%3\n\t"						\
-	"move\t%1,$0\n\t"						\
-	"j\t2b\n\t"							\
-	".previous\n\t"							\
-	".section\t__ex_table,\"a\"\n\t"				\
-	".dword\t1b,3b\n\t"						\
-	".previous"							\
-	:"=r" (__gu_err), "=r" (__gu_val)				\
-	:"o" (__m(__gu_addr)), "i" (-EFAULT));				\
+	"1:	" insn "	%1, %3				\n"	\
+	"2:							\n"	\
+	"	.section .fixup,\"ax\"				\n"	\
+	"3:	li	%0, %4					\n"	\
+	"	j	2b					\n"	\
+	"	.previous					\n"	\
+	"	.section __ex_table,\"a\"			\n"	\
+	"	"__UA_ADDR "\t1b, 3b				\n"	\
+	"	.previous					\n"	\
+	: "=r" (__gu_err), "=r" (__gu_val)				\
+	: "0" (__gu_err), "o" (__m(__gu_addr)), "i" (-EFAULT));		\
+})
+
+/*
+ * Get a long long 64 using 32 bit registers.
+ */
+#define __get_user_asm_ll32(__gu_err)					\
+({									\
+	__asm__ __volatile__(						\
+	"1:	lw	%1, %3					\n"	\
+	"2:	lw	%D1, %4					\n"	\
+	"	move	%0, $0					\n"	\
+	"3:	.section	.fixup,\"ax\"			\n"	\
+	"4:	li	%0, %5					\n"	\
+	"	move	%1, $0					\n"	\
+	"	move	%D1, $0					\n"	\
+	"	j	3b					\n"	\
+	"	.previous					\n"	\
+	"	.section	__ex_table,\"a\"		\n"	\
+	"	" __UA_ADDR "	1b, 4b				\n"	\
+	"	" __UA_ADDR "	2b, 4b				\n"	\
+	"	.previous					\n"	\
+	: "=r" (__gu_err), "=&r" (__gu_val)				\
+	: "0" (__gu_err), "o" (__m(__gu_addr)),				\
+	  "o" (__m(__gu_addr + 4)), "i" (-EFAULT));			\
 })
 
 extern void __get_user_unknown(void);
 
+/*
+ * Yuck.  We need two variants, one for 64bit operation and one
+ * for 32 bit mode and old iron.
+ */
+#ifdef __mips64
+#define __PUT_USER_DW(__pu_val) __put_user_asm("sd", __pu_val)
+#else
+#define __PUT_USER_DW(__pu_val) __put_user_asm_ll32(__pu_val)
+#endif
+
 #define __put_user_nocheck(x,ptr,size)					\
 ({									\
-	long __pu_err;							\
+	long __pu_err = 0;						\
 	__typeof__(*(ptr)) __pu_val;					\
 	long __pu_addr;							\
 	__pu_val = (x);							\
 	__pu_addr = (long) (ptr);					\
-	__asm__("":"=r" (__pu_err));					\
 	switch (size) {							\
-		case 1: __put_user_asm("sb"); break;			\
-		case 2: __put_user_asm("sh"); break;			\
-		case 4: __put_user_asm("sw"); break;			\
-		case 8: __put_user_asm("sd"); break;			\
-		default: __put_user_unknown(); break;			\
+	case 1: __put_user_asm("sb", __pu_val); break;			\
+	case 2: __put_user_asm("sh", __pu_val); break;			\
+	case 4: __put_user_asm("sw", __pu_val); break;			\
+	case 8: __PUT_USER_DW(__pu_val); break;				\
+	default: __put_user_unknown(); break;				\
 	}								\
 	__pu_err;							\
 })
 
 #define __put_user_check(x,ptr,size)					\
 ({									\
+	__typeof__(*(ptr)) __pu_val = (x);				\
+	long __pu_addr = (long) (ptr);					\
 	long __pu_err;							\
-	__typeof__(*(ptr)) __pu_val;					\
-	long __pu_addr;							\
-	__pu_val = (x);							\
-	__pu_addr = (long) (ptr);					\
-	__asm__("":"=r" (__pu_err));					\
-	if (access_ok(VERIFY_WRITE, __pu_addr, size)) {			\
+									\
+	__pu_err = verify_area(VERIFY_WRITE, (void *) __pu_addr, size);	\
+									\
+	if (likely(!__pu_err)) {					\
 		switch (size) {						\
-		case 1: __put_user_asm("sb"); break;			\
-		case 2: __put_user_asm("sh"); break;			\
-		case 4: __put_user_asm("sw"); break;			\
-		case 8: __put_user_asm("sd"); break;			\
+		case 1: __put_user_asm("sb", __pu_val); break;		\
+		case 2: __put_user_asm("sh", __pu_val); break;		\
+		case 4: __put_user_asm("sw", __pu_val); break;		\
+		case 8: __PUT_USER_DW(__pu_val); break;			\
 		default: __put_user_unknown(); break;			\
 		}							\
 	}								\
 	__pu_err;							\
 })
 
-#define __put_user_asm(insn)						\
+#define __put_user_asm(insn, __pu_val)					\
 ({									\
 	__asm__ __volatile__(						\
-	"1:\t" insn "\t%z1, %2\t\t\t# __put_user_asm\n\t"		\
-	"move\t%0, $0\n"						\
-	"2:\n\t"							\
-	".section\t.fixup,\"ax\"\n"					\
-	"3:\tli\t%0, %3\n\t"						\
-	"j\t2b\n\t"							\
-	".previous\n\t"							\
-	".section\t__ex_table,\"a\"\n\t"				\
-	".dword\t1b, 3b\n\t"						\
-	".previous"							\
-	:"=r" (__pu_err)						\
-	:"Jr" (__pu_val), "o" (__m(__pu_addr)), "i" (-EFAULT));		\
+	"1:	" insn "	%z2, %3		# __put_user_asm\n"	\
+	"2:							\n"	\
+	"	.section	.fixup,\"ax\"			\n"	\
+	"3:	li	%0, %4					\n"	\
+	"	j	2b					\n"	\
+	"	.previous					\n"	\
+	"	.section	__ex_table,\"a\"		\n"	\
+	"	" __UA_ADDR "	1b, 3b				\n"	\
+	"	.previous					\n"	\
+	: "=r" (__pu_err)						\
+	: "0" (__pu_err), "Jr" (__pu_val), "o" (__m(__pu_addr)),	\
+	  "i" (-EFAULT));						\
+})
+
+#define __put_user_asm_ll32(__pu_val)					\
+({									\
+	__asm__ __volatile__(						\
+	"1:	sw	%2, %3		# __put_user_asm_ll32	\n"	\
+	"2:	sw	%D2, %4					\n"	\
+	"3:							\n"	\
+	"	.section	.fixup,\"ax\"			\n"	\
+	"4:	li	%0, %5					\n"	\
+	"	j	3b					\n"	\
+	"	.previous					\n"	\
+	"	.section	__ex_table,\"a\"		\n"	\
+	"	" __UA_ADDR "	1b, 4b				\n"	\
+	"	" __UA_ADDR "	2b, 4b				\n"	\
+	"	.previous"						\
+	: "=r" (__pu_err)						\
+	: "0" (__pu_err), "r" (__pu_val), "o" (__m(__pu_addr)),		\
+	  "o" (__m(__pu_addr + 4)), "i" (-EFAULT));			\
 })
 
 extern void __put_user_unknown(void);
@@ -307,7 +401,7 @@ extern void __put_user_unknown(void);
 #ifdef MODULE
 #define __MODULE_JAL(destination)					\
 	".set\tnoat\n\t"						\
-	"dla\t$1, " #destination "\n\t"					 \
+	__UA_LA "\t$1, " #destination "\n\t" 				\
 	"jalr\t$1\n\t"							\
 	".set\tat\n\t"
 #else
@@ -362,6 +456,9 @@ extern size_t __copy_user(void *__to, co
 	__cu_len;							\
 })
 
+#define __copy_to_user_inatomic __copy_to_user
+#define __copy_from_user_inatomic __copy_from_user
+
 /*
  * copy_to_user: - Copy a block of data into user space.
  * @to:   Destination address, in user space.
@@ -403,10 +500,9 @@ extern size_t __copy_user(void *__to, co
 	".set\tnoreorder\n\t"						\
 	__MODULE_JAL(__copy_user)					\
 	".set\tnoat\n\t"						\
-	"daddu\t$1, %1, %2\n\t"						\
+	__UA_ADDU "\t$1, %1, %2\n\t"					\
 	".set\tat\n\t"							\
-	".set\treorder\n\t"						\
-	"move\t%0, $6"							\
+	".set\treorder"							\
 	: "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r)	\
 	:								\
 	: "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31",		\
@@ -499,7 +595,7 @@ __clear_user(void *addr, __kernel_size_t
 		"move\t%0, $6"
 		: "=r" (res)
 		: "r" (addr), "r" (size)
-		: "$4", "$5", "$6", "$8", "$9", "$31");
+		: "$4", "$5", "$6", __UA_t0, __UA_t1, "$31");
 
 	return res;
 }
@@ -547,7 +643,7 @@ __strncpy_from_user(char *__to, const ch
 		"move\t%0, $2"
 		: "=r" (res)
 		: "r" (__to), "r" (__from), "r" (__len)
-		: "$2", "$3", "$4", "$5", "$6", "$8", "$31", "memory");
+		: "$2", "$3", "$4", "$5", "$6", __UA_t0, "$31", "memory");
 
 	return res;
 }
@@ -583,7 +679,7 @@ strncpy_from_user(char *__to, const char
 		"move\t%0, $2"
 		: "=r" (res)
 		: "r" (__to), "r" (__from), "r" (__len)
-		: "$2", "$3", "$4", "$5", "$6", "$8", "$31", "memory");
+		: "$2", "$3", "$4", "$5", "$6", __UA_t0, "$31", "memory");
 
 	return res;
 }
@@ -599,7 +695,7 @@ static inline long __strlen_user(const c
 		"move\t%0, $2"
 		: "=r" (res)
 		: "r" (s)
-		: "$2", "$4", "$8", "$31");
+		: "$2", "$4", __UA_t0, "$31");
 
 	return res;
 }
@@ -628,7 +724,24 @@ static inline long strlen_user(const cha
 		"move\t%0, $2"
 		: "=r" (res)
 		: "r" (s)
-		: "$2", "$4", "$8", "$31");
+		: "$2", "$4", __UA_t0, "$31");
+
+	return res;
+}
+
+/* Returns: 0 if bad, string length+1 (memory size) of string if ok */
+static inline long __strnlen_user(const char *s, long n)
+{
+	long res;
+
+	__asm__ __volatile__(
+		"move\t$4, %1\n\t"
+		"move\t$5, %2\n\t"
+		__MODULE_JAL(__strnlen_user_nocheck_asm)
+		"move\t%0, $2"
+		: "=r" (res)
+		: "r" (s), "r" (n)
+		: "$2", "$4", "$5", __UA_t0, "$31");
 
 	return res;
 }
@@ -636,13 +749,16 @@ static inline long strlen_user(const cha
 /*
  * strlen_user: - Get the size of a string in user space.
  * @str: The string to measure.
- * @n:   The maximum valid length
+ *
+ * Context: User context only.  This function may sleep.
  *
  * Get the size of a NUL-terminated string in user space.
  *
  * Returns the size of the string INCLUDING the terminating NUL.
  * On exception, returns 0.
- * If the string is too long, returns a value greater than @n.
+ *
+ * If there is a limit on the length of a valid string, you may wish to
+ * consider using strnlen_user() instead.
  */
 static inline long strnlen_user(const char *s, long n)
 {
@@ -655,7 +771,7 @@ static inline long strnlen_user(const ch
 		"move\t%0, $2"
 		: "=r" (res)
 		: "r" (s), "r" (n)
-		: "$2", "$4", "$5", "$8", "$31");
+		: "$2", "$4", "$5", __UA_t0, "$31");
 
 	return res;
 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips64/unaligned.h linux-2.4.29-pre3/include/asm-mips64/unaligned.h
--- linux-2.4.28/include/asm-mips64/unaligned.h	2003-08-25 11:44:44.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips64/unaligned.h	2004-12-22 16:07:09.904670816 +0000
@@ -3,152 +3,142 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 1999, 2000, 2001 by Ralf Baechle
+ * Copyright (C) 1996, 1999, 2000, 2001, 2003 by Ralf Baechle
  * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc.
  */
 #ifndef _ASM_UNALIGNED_H
 #define _ASM_UNALIGNED_H
 
-extern void __get_unaligned_bad_length(void);
-extern void __put_unaligned_bad_length(void);
+#include <linux/types.h>
 
 /*
- * Load quad unaligned.
+ * get_unaligned - get value from possibly mis-aligned location
+ * @ptr: pointer to value
+ *
+ * This macro should be used for accessing values larger in size than
+ * single bytes at locations that are expected to be improperly aligned,
+ * e.g. retrieving a u16 value from a location not u16-aligned.
+ *
+ * Note that unaligned accesses can be very expensive on some architectures.
  */
-static inline unsigned long __ldq_u(const unsigned long * __addr)
-{
-	unsigned long __res;
-
-	__asm__("uld\t%0,%1"
-		: "=&r" (__res)
-		: "m" (*__addr));
+#define get_unaligned(ptr) \
+	((__typeof__(*(ptr)))__get_unaligned((ptr), sizeof(*(ptr))))
 
-	return __res;
-}
+/*
+ * put_unaligned - put value to a possibly mis-aligned location
+ * @val: value to place
+ * @ptr: pointer to location
+ *
+ * This macro should be used for placing values larger in size than
+ * single bytes at locations that are expected to be improperly aligned,
+ * e.g. writing a u16 value to a location not u16-aligned.
+ *
+ * Note that unaligned accesses can be very expensive on some architectures.
+ */
+#define put_unaligned(x,ptr) \
+	__put_unaligned((__u64)(x), (ptr), sizeof(*(ptr)))
 
 /*
- * Load long unaligned.
+ * This is a silly but good way to make sure that
+ * the get/put functions are indeed always optimized,
+ * and that we use the correct sizes.
  */
-static inline unsigned long __ldl_u(const unsigned int * __addr)
-{
-	unsigned long __res;
+extern void bad_unaligned_access_length(void);
 
-	__asm__("ulw\t%0,%1"
-		: "=&r" (__res)
-		: "m" (*__addr));
+/*
+ * EGCS 1.1 knows about arbitrary unaligned loads.  Define some
+ * packed structures to talk about such things with.
+ */
 
-	return __res;
-}
+struct __una_u64 { __u64 x __attribute__((packed)); };
+struct __una_u32 { __u32 x __attribute__((packed)); };
+struct __una_u16 { __u16 x __attribute__((packed)); };
 
 /*
- * Load word unaligned.
+ * Elemental unaligned loads
  */
-static inline unsigned long __ldw_u(const unsigned short * __addr)
+
+static inline __u64 __uldq(const __u64 * r11)
 {
-	unsigned long __res;
+	const struct __una_u64 *ptr = (const struct __una_u64 *) r11;
+	return ptr->x;
+}
 
-	__asm__("ulh\t%0,%1"
-		: "=&r" (__res)
-		: "m" (*__addr));
+static inline __u32 __uldl(const __u32 * r11)
+{
+	const struct __una_u32 *ptr = (const struct __una_u32 *) r11;
+	return ptr->x;
+}
 
-	return __res;
+static inline __u16 __uldw(const __u16 * r11)
+{
+	const struct __una_u16 *ptr = (const struct __una_u16 *) r11;
+	return ptr->x;
 }
 
 /*
- * Store quad unaligned.
+ * Elemental unaligned stores
  */
-static inline void __stq_u(unsigned long __val, unsigned long * __addr)
+
+static inline void __ustq(__u64 r5, __u64 * r11)
 {
-	__asm__("usd\t%1, %0"
-		: "=m" (*__addr)
-		: "r" (__val));
+	struct __una_u64 *ptr = (struct __una_u64 *) r11;
+	ptr->x = r5;
 }
 
-/*
- * Store long unaligned.
- */
-static inline void __stl_u(unsigned long __val, unsigned int * __addr)
+static inline void __ustl(__u32 r5, __u32 * r11)
 {
-	__asm__("usw\t%1, %0"
-		: "=m" (*__addr)
-		: "r" (__val));
+	struct __una_u32 *ptr = (struct __una_u32 *) r11;
+	ptr->x = r5;
 }
 
-/*
- * Store word unaligned.
- */
-static inline void __stw_u(unsigned long __val, unsigned short * __addr)
+static inline void __ustw(__u16 r5, __u16 * r11)
 {
-	__asm__("ush\t%1, %0"
-		: "=m" (*__addr)
-		: "r" (__val));
+	struct __una_u16 *ptr = (struct __una_u16 *) r11;
+	ptr->x = r5;
 }
 
-/*
- * get_unaligned - get value from possibly mis-aligned location
- * @ptr: pointer to value
- *
- * This macro should be used for accessing values larger in size than
- * single bytes at locations that are expected to be improperly aligned,
- * e.g. retrieving a u16 value from a location not u16-aligned.
- *
- * Note that unaligned accesses can be very expensive on some architectures.
- */
-#define get_unaligned(ptr)						\
-({									\
-	__typeof__(*(ptr)) __val;					\
-									\
-	switch (sizeof(*(ptr))) {					\
-	case 1:								\
-		__val = *(const unsigned char *)(ptr);			\
-		break;							\
-	case 2:								\
-		__val = __ldw_u((const unsigned short *)(ptr));		\
-		break;							\
-	case 4:								\
-		__val = __ldl_u((const unsigned int *)(ptr));		\
-		break;							\
-	case 8:								\
-		__val = __ldq_u((const unsigned long *)(ptr));		\
-		break;							\
-	default:							\
-		__get_unaligned_bad_length();				\
-		break;							\
-	}								\
-									\
-	__val;								\
-})
+static inline __u64 __get_unaligned(const void *ptr, size_t size)
+{
+	__u64 val;
 
-/*
- * put_unaligned - put value to a possibly mis-aligned location
- * @val: value to place
- * @ptr: pointer to location
- *
- * This macro should be used for placing values larger in size than
- * single bytes at locations that are expected to be improperly aligned,
- * e.g. writing a u16 value to a location not u16-aligned.
- *
- * Note that unaligned accesses can be very expensive on some architectures.
- */
-#define put_unaligned(val,ptr)						\
-do {									\
-	switch (sizeof(*(ptr))) {					\
-	case 1:								\
-		*(unsigned char *)(ptr) = (val);			\
-		break;							\
-	case 2:								\
-		__stw_u((val), (unsigned short *)(ptr));		\
-		break;							\
-	case 4:								\
-		__stl_u((val), (unsigned int *)(ptr));			\
-		break;							\
-	case 8:								\
-		__stq_u((val), (unsigned long long *)(ptr));		\
-		break;							\
-	default:							\
-		__put_unaligned_bad_length();				\
-		break;							\
-	}								\
-} while(0)
+	switch (size) {
+	case 1:
+		val = *(const __u8 *)ptr;
+		break;
+	case 2:
+		val = __uldw((const __u16 *)ptr);
+		break;
+	case 4:
+		val = __uldl((const __u32 *)ptr);
+		break;
+	case 8:
+		val = __uldq((const __u64 *)ptr);
+		break;
+	default:
+		bad_unaligned_access_length();
+	}
+	return val;
+}
+
+static inline void __put_unaligned(__u64 val, void *ptr, size_t size)
+{
+	switch (size) {
+	      case 1:
+		*(__u8 *)ptr = (val);
+	        break;
+	      case 2:
+		__ustw(val, (__u16 *)ptr);
+		break;
+	      case 4:
+		__ustl(val, (__u32 *)ptr);
+		break;
+	      case 8:
+		__ustq(val, (__u64 *)ptr);
+		break;
+	      default:
+	    	bad_unaligned_access_length();
+	}
+}
 
 #endif /* _ASM_UNALIGNED_H */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips64/unistd.h linux-2.4.29-pre3/include/asm-mips64/unistd.h
--- linux-2.4.28/include/asm-mips64/unistd.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips64/unistd.h	2004-12-22 16:07:23.716571088 +0000
@@ -268,8 +268,6 @@
 #define __NR_O32_Linux			4000
 #define __NR_O32_Linux_syscalls		240
 
-#define __NR_O32_Linux_syscalls		240
-
 #if _MIPS_SIM == _MIPS_SIM_ABI64
 
 /*
@@ -493,7 +491,7 @@
 #define __NR_semtimedop			(__NR_Linux + 214)
 
 /*
- * Offset of the last Linux flavoured syscall
+ * Offset of the last Linux 64-bit flavoured syscall
  */
 #define __NR_Linux_syscalls		214
 
@@ -732,7 +730,7 @@
 /*
  * Offset of the last N32 flavoured syscall
  */
-#define __NR_N32_Linux_syscalls		219
+#define __NR_Linux_syscalls		219
 
 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
 
@@ -756,7 +754,8 @@ type name(void) \
 	".set\treorder" \
 	: "=&r" (__v0), "=r" (__a3) \
 	: "i" (__NR_##name) \
-	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
+	  "memory"); \
 	\
 	if (__a3 == 0) \
 		return (type) __v0; \
@@ -783,7 +782,8 @@ type name(atype a) \
 	".set\treorder" \
 	: "=&r" (__v0), "=r" (__a3) \
 	: "r" (__a0), "i" (__NR_##name) \
-	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
+	  "memory"); \
 	\
 	if (__a3 == 0) \
 		return (type) __v0; \
@@ -807,7 +807,8 @@ type name(atype a, btype b) \
 	".set\treorder" \
 	: "=&r" (__v0), "=r" (__a3) \
 	: "r" (__a0), "r" (__a1), "i" (__NR_##name) \
-	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
+	  "memory"); \
 	\
 	if (__a3 == 0) \
 		return (type) __v0; \
@@ -832,7 +833,8 @@ type name(atype a, btype b, ctype c) \
 	".set\treorder" \
 	: "=&r" (__v0), "=r" (__a3) \
 	: "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name) \
-	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
+	  "memory"); \
 	\
 	if (__a3 == 0) \
 		return (type) __v0; \
@@ -857,7 +859,8 @@ type name(atype a, btype b, ctype c, dty
 	".set\treorder" \
 	: "=&r" (__v0), "+r" (__a3) \
 	: "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name) \
-	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
+	  "memory"); \
 	\
 	if (__a3 == 0) \
 		return (type) __v0; \
@@ -865,7 +868,7 @@ type name(atype a, btype b, ctype c, dty
 	return -1; \
 }
 
-#if (_MIPS_SIM == _MIPS_SIM_ABIN32)
+#if (_MIPS_SIM == _MIPS_SIM_ABI32)
 
 /*
  * Using those means your brain needs more than an oil change ;-)
@@ -893,7 +896,8 @@ type name(atype a, btype b, ctype c, dty
 	: "=&r" (__v0), "+r" (__a3) \
 	: "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name), \
 	  "m" ((unsigned long)e) \
-	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
+	  "memory"); \
 	\
 	if (__a3 == 0) \
 		return (type) __v0; \
@@ -925,7 +929,8 @@ type name(atype a, btype b, ctype c, dty
 	: "=&r" (__v0), "+r" (__a3) \
 	: "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name), \
 	  "m" ((unsigned long)e), "m" ((unsigned long)f) \
-	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	: "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
+	  "memory"); \
 	\
 	if (__a3 == 0) \
 		return (type) __v0; \
@@ -933,9 +938,9 @@ type name(atype a, btype b, ctype c, dty
 	return -1; \
 }
 
-#endif /* (_MIPS_SIM == _MIPS_SIM_ABIN32) */
+#endif /* (_MIPS_SIM == _MIPS_SIM_ABI32) */
 
-#if (_MIPS_SIM == _MIPS_SIM_NABIN32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
+#if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
 
 #define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
 type name (atype a,btype b,ctype c,dtype d,etype e) \
@@ -953,9 +958,10 @@ type name (atype a,btype b,ctype c,dtype
 	"syscall\n\t" \
 	"move\t%0, $2\n\t" \
 	".set\treorder" \
-	: "=&r" (__v0), "+r" (__a3), "+r" (__a4) \
-	: "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name) \
-	: "$2","$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	: "=&r" (__v0), "+r" (__a3) \
+	: "r" (__a0), "r" (__a1), "r" (__a2), "r" (__a4), "i" (__NR_##name) \
+	: "$2", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
+	  "memory"); \
 	\
 	if (__a3 == 0) \
 		return (type) __v0; \
@@ -983,7 +989,8 @@ type name (atype a,btype b,ctype c,dtype
 	: "=&r" (__v0), "+r" (__a3) \
 	: "r" (__a0), "r" (__a1), "r" (__a2), "r" (__a4), "r" (__a5), \
 	  "i" (__NR_##name) \
-	: "$2","$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24"); \
+	: "$2", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
+	  "memory"); \
 	\
 	if (__a3 == 0) \
 		return (type) __v0; \
@@ -991,7 +998,7 @@ type name (atype a,btype b,ctype c,dtype
 	return -1; \
 }
 
-#endif /* (_MIPS_SIM == _MIPS_SIM_NABIN32) || (_MIPS_SIM == _MIPS_SIM_ABI64) */
+#endif /* (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) */
 
 #ifdef __KERNEL_SYSCALLS__
 
@@ -1017,7 +1024,7 @@ static inline _syscall1(int,dup,int,fd)
 static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
 static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
 static inline _syscall1(int,close,int,fd)
-static inline _syscall1(int,_exit,int,exitcode)
+static inline _syscall1(void,_exit,int,exitcode)
 static inline _syscall4(pid_t,wait4,pid_t,pid,int *,stat_addr,int,options,struct rusage *,ru)
 static inline _syscall1(int,delete_module,const char *,name)
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips64/vga.h linux-2.4.29-pre3/include/asm-mips64/vga.h
--- linux-2.4.28/include/asm-mips64/vga.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips64/vga.h	2004-12-22 16:07:32.423247472 +0000
@@ -0,0 +1,20 @@
+/*
+ *	Access to VGA videoram
+ *
+ *	(c) 1998 Martin Mares <mj@ucw.cz>
+ */
+
+#ifndef _LINUX_ASM_VGA_H_
+#define _LINUX_ASM_VGA_H_
+
+/*
+ *	On the PC, we can just recalculate addresses and then
+ *	access the videoram directly without any black magic.
+ */
+
+#define VGA_MAP_MEM(x) ((unsigned long)0xb0000000 + (unsigned long)(x))
+
+#define vga_readb(x) (*(x))
+#define vga_writeb(x,y) (*(y) = (x))
+
+#endif
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-mips64/war.h linux-2.4.29-pre3/include/asm-mips64/war.h
--- linux-2.4.28/include/asm-mips64/war.h	2003-08-25 11:44:44.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-mips64/war.h	2004-12-22 16:07:31.966316936 +0000
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2002 by Ralf Baechle
+ * Copyright (C) 2002, 2004 by Ralf Baechle
  */
 #ifndef _ASM_WAR_H
 #define _ASM_WAR_H
@@ -11,6 +11,15 @@
 #include <linux/config.h>
 
 /*
+ * Another R4600 erratum.  Due to the lack of errata information the exact
+ * technical details aren't known.  I've experimentally found that disabling
+ * interrupts during indexed I-cache flushes seems to be sufficient to deal
+ * with the issue.
+ *
+ * #define R4600_V1_INDEX_ICACHEOP_WAR 1
+ */
+
+/*
  * Pleasures of the R4600 V1.x.  Cite from the IDT R4600 V1.7 errata:
  *
  *  18. The CACHE instructions Hit_Writeback_Invalidate_D, Hit_Writeback_D,
@@ -59,6 +68,7 @@
  */
 #ifdef CONFIG_SGI_IP22
 
+#define R4600_V1_INDEX_ICACHEOP_WAR	1
 #define R4600_V1_HIT_CACHEOP_WAR	1
 #define R4600_V2_HIT_CACHEOP_WAR	1
 
@@ -159,8 +169,19 @@
 #endif
 
 /*
+ * On the RM9000 there is a problem which makes the CreateDirtyExclusive
+ * cache operation unusable on SMP systems.
+ */
+#if defined(CONFIG_MOMENCO_JAGUAR_ATX) || defined(CONFIG_PMC_YOSEMITE)
+#define  RM9000_CDEX_SMP_WAR		1
+#endif
+
+/*
  * Workarounds default to off
  */
+#ifndef R4600_V1_INDEX_ICACHEOP_WAR
+#define R4600_V1_INDEX_ICACHEOP_WAR	0
+#endif
 #ifndef R4600_V1_HIT_CACHEOP_WAR
 #define R4600_V1_HIT_CACHEOP_WAR	0
 #endif
@@ -185,5 +206,8 @@
 #ifndef TX49XX_ICACHE_INDEX_INV_WAR
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
 #endif
+#ifndef RM9000_CDEX_SMP_WAR
+#define RM9000_CDEX_SMP_WAR		0
+#endif
 
 #endif /* _ASM_WAR_H */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-sparc/elf.h linux-2.4.29-pre3/include/asm-sparc/elf.h
--- linux-2.4.28/include/asm-sparc/elf.h	2000-07-12 02:02:37.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-sparc/elf.h	2004-12-22 16:07:21.714875392 +0000
@@ -81,7 +81,7 @@ typedef struct {
    the loader.  We need to make sure that it is out of the way of the program
    that it will "exec", and that there is sufficient room for the brk.  */
 
-#define ELF_ET_DYN_BASE         (0x08000000)
+#define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE)
 
 /* This yields a mask that user programs can use to figure out what
    instruction set this cpu supports.  This can NOT be done in userspace
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/asm-x86_64/socket32.h linux-2.4.29-pre3/include/asm-x86_64/socket32.h
--- linux-2.4.28/include/asm-x86_64/socket32.h	2002-11-28 23:53:15.000000000 +0000
+++ linux-2.4.29-pre3/include/asm-x86_64/socket32.h	2004-12-22 16:06:00.707190432 +0000
@@ -45,6 +45,11 @@ struct cmsghdr32 {
 				    (struct cmsghdr32 *)(ctl) : \
 				    (struct cmsghdr32 *)NULL)
 #define CMSG32_FIRSTHDR(msg)	__CMSG32_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
+#define CMSG32_OK(ucmlen, ucmsg, mhdr) \
+	((ucmlen) >= sizeof(struct cmsghdr) && \
+	 (ucmlen) <= (unsigned long) \
+	 ((mhdr)->msg_controllen - \
+	  ((char *)(ucmsg) - (char *)(mhdr)->msg_control)))
 
 __inline__ struct cmsghdr32 *__cmsg32_nxthdr(void *__ctl, __kernel_size_t __size,
 					      struct cmsghdr32 *__cmsg, int __cmsg_len)
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/linux/ata.h linux-2.4.29-pre3/include/linux/ata.h
--- linux-2.4.28/include/linux/ata.h	2004-12-22 16:17:21.221736496 +0000
+++ linux-2.4.29-pre3/include/linux/ata.h	2004-12-22 16:05:50.000000000 +0000
@@ -24,6 +24,8 @@
 #ifndef __LINUX_ATA_H__
 #define __LINUX_ATA_H__
 
+#include <linux/types.h>
+
 /* defines only for the constants which don't work well as enums */
 #define ATA_DMA_BOUNDARY	0xffffUL
 #define ATA_DMA_MASK		0xffffffffULL
@@ -33,8 +35,6 @@ enum {
 	ATA_MAX_DEVICES		= 2,	/* per bus/port */
 	ATA_MAX_PRD		= 256,	/* we could make these 256/256 */
 	ATA_SECT_SIZE		= 512,
-	ATA_SECT_SIZE_MASK	= (ATA_SECT_SIZE - 1),
-	ATA_SECT_DWORDS		= ATA_SECT_SIZE / sizeof(u32),
 
 	ATA_ID_WORDS		= 256,
 	ATA_ID_PROD_OFS		= 27,
@@ -142,6 +142,10 @@ enum {
 	XFER_PIO_2		= 0x0A,
 	XFER_PIO_1		= 0x09,
 	XFER_PIO_0		= 0x08,
+	XFER_SW_DMA_2		= 0x12,
+	XFER_SW_DMA_1		= 0x11,
+	XFER_SW_DMA_0		= 0x10,
+	XFER_PIO_SLOW		= 0x00,
 
 	/* ATAPI stuff */
 	ATAPI_PKT_DMA		= (1 << 0),
@@ -217,24 +221,24 @@ struct ata_taskfile {
 	u8			command;	/* IO operation */
 };
 
-#define ata_id_is_ata(dev)	(((dev)->id[0] & (1 << 15)) == 0)
-#define ata_id_rahead_enabled(dev) ((dev)->id[85] & (1 << 6))
-#define ata_id_wcache_enabled(dev) ((dev)->id[85] & (1 << 5))
-#define ata_id_has_flush(dev) ((dev)->id[83] & (1 << 12))
-#define ata_id_has_flush_ext(dev) ((dev)->id[83] & (1 << 13))
-#define ata_id_has_lba48(dev)	((dev)->id[83] & (1 << 10))
-#define ata_id_has_wcache(dev)	((dev)->id[82] & (1 << 5))
-#define ata_id_has_pm(dev)	((dev)->id[82] & (1 << 3))
-#define ata_id_has_lba(dev)	((dev)->id[49] & (1 << 9))
-#define ata_id_has_dma(dev)	((dev)->id[49] & (1 << 8))
-#define ata_id_removeable(dev)	((dev)->id[0] & (1 << 7))
-#define ata_id_u32(dev,n)	\
-	(((u32) (dev)->id[(n) + 1] << 16) | ((u32) (dev)->id[(n)]))
-#define ata_id_u64(dev,n)	\
-	( ((u64) dev->id[(n) + 3] << 48) |	\
-	  ((u64) dev->id[(n) + 2] << 32) |	\
-	  ((u64) dev->id[(n) + 1] << 16) |	\
-	  ((u64) dev->id[(n) + 0]) )
+#define ata_id_is_ata(id)	(((id)[0] & (1 << 15)) == 0)
+#define ata_id_rahead_enabled(id) ((id)[85] & (1 << 6))
+#define ata_id_wcache_enabled(id) ((id)[85] & (1 << 5))
+#define ata_id_has_flush(id) ((id)[83] & (1 << 12))
+#define ata_id_has_flush_ext(id) ((id)[83] & (1 << 13))
+#define ata_id_has_lba48(id)	((id)[83] & (1 << 10))
+#define ata_id_has_wcache(id)	((id)[82] & (1 << 5))
+#define ata_id_has_pm(id)	((id)[82] & (1 << 3))
+#define ata_id_has_lba(id)	((id)[49] & (1 << 9))
+#define ata_id_has_dma(id)	((id)[49] & (1 << 8))
+#define ata_id_removeable(id)	((id)[0] & (1 << 7))
+#define ata_id_u32(id,n)	\
+	(((u32) (id)[(n) + 1] << 16) | ((u32) (id)[(n)]))
+#define ata_id_u64(id,n)	\
+	( ((u64) (id)[(n) + 3] << 48) |	\
+	  ((u64) (id)[(n) + 2] << 32) |	\
+	  ((u64) (id)[(n) + 1] << 16) |	\
+	  ((u64) (id)[(n) + 0]) )
 
 static inline int atapi_cdb_len(u16 *dev_id)
 {
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/linux/cd1400.h linux-2.4.29-pre3/include/linux/cd1400.h
--- linux-2.4.28/include/linux/cd1400.h	1999-09-02 18:22:40.000000000 +0000
+++ linux-2.4.29-pre3/include/linux/cd1400.h	2004-12-22 16:06:02.756878832 +0000
@@ -3,7 +3,7 @@
 /*
  *	cd1400.h  -- cd1400 UART hardware info.
  *
- *	Copyright (C) 1996-1998  Stallion Technologies (support@stallion.oz.au).
+ *	Copyright (C) 1996-1998  Stallion Technologies
  *	Copyright (C) 1994-1996  Greg Ungerer.
  *
  *	This program is free software; you can redistribute it and/or modify
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/linux/cdk.h linux-2.4.29-pre3/include/linux/cdk.h
--- linux-2.4.28/include/linux/cdk.h	1999-09-02 18:22:40.000000000 +0000
+++ linux-2.4.29-pre3/include/linux/cdk.h	2004-12-22 16:07:05.999264528 +0000
@@ -3,7 +3,7 @@
 /*
  *	cdk.h  -- CDK interface definitions.
  *
- *	Copyright (C) 1996-1998  Stallion Technologies (support@stallion.oz.au).
+ *	Copyright (C) 1996-1998  Stallion Technologies
  *	Copyright (C) 1994-1996  Greg Ungerer.
  *
  *	This program is free software; you can redistribute it and/or modify
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/linux/comstats.h linux-2.4.29-pre3/include/linux/comstats.h
--- linux-2.4.28/include/linux/comstats.h	1999-09-02 18:22:40.000000000 +0000
+++ linux-2.4.29-pre3/include/linux/comstats.h	2004-12-22 16:05:58.089588368 +0000
@@ -3,7 +3,7 @@
 /*
  *	comstats.h  -- Serial Port Stats.
  *
- *	Copyright (C) 1996-1998  Stallion Technologies (support@stallion.oz.au).
+ *	Copyright (C) 1996-1998  Stallion Technologies
  *	Copyright (C) 1994-1996  Greg Ungerer.
  *
  *	This program is free software; you can redistribute it and/or modify
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/linux/delay.h linux-2.4.29-pre3/include/linux/delay.h
--- linux-2.4.28/include/linux/delay.h	2001-01-04 20:50:17.000000000 +0000
+++ linux-2.4.29-pre3/include/linux/delay.h	2004-12-22 16:06:05.029533336 +0000
@@ -9,9 +9,64 @@
 
 extern unsigned long loops_per_jiffy;
 
+#include <linux/time.h>
+#include <linux/sched.h>
 #include <asm/delay.h>
 
 /*
+ * Convert jiffies to milliseconds and back.
+ *
+ * Avoid unnecessary multiplications/divisions in the
+ * two most common HZ cases:
+ */
+static inline unsigned int jiffies_to_msecs(const unsigned long j)
+{
+#if HZ <= 1000 && !(1000 % HZ)
+	return (1000 / HZ) * j;
+#elif HZ > 1000 && !(HZ % 1000)
+	return (j + (HZ / 1000) - 1)/(HZ / 1000);
+#else
+	return (j * 1000) / HZ;
+#endif
+}
+
+static inline unsigned int jiffies_to_usecs(const unsigned long j)
+{
+#if HZ <= 1000 && !(1000 % HZ)
+	return (1000000 / HZ) * j;
+#elif HZ > 1000 && !(HZ % 1000)
+	return (j*1000 + (HZ - 1000))/(HZ / 1000);
+#else
+	return (j * 1000000) / HZ;
+#endif
+}
+
+static inline unsigned long msecs_to_jiffies(const unsigned int m)
+{
+	if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
+		return MAX_JIFFY_OFFSET;
+#if HZ <= 1000 && !(1000 % HZ)
+	return (m + (1000 / HZ) - 1) / (1000 / HZ);
+#elif HZ > 1000 && !(HZ % 1000)
+	return m * (HZ / 1000);
+#else
+	return (m * HZ + 999) / 1000;
+#endif
+}
+
+static inline void msleep(unsigned long msecs)
+{
+        set_current_state(TASK_UNINTERRUPTIBLE);
+        schedule_timeout(msecs_to_jiffies(msecs) + 1);
+}
+
+static inline void ssleep(unsigned long secs)
+{
+        set_current_state(TASK_UNINTERRUPTIBLE);
+        schedule_timeout((HZ * secs) + 1);
+}
+
+/*
  * Using udelay() for intervals greater than a few milliseconds can
  * risk overflow for high loops_per_jiffy (high bogomips) machines. The
  * mdelay() provides a wrapper to prevent this.  For delays greater
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/linux/dqblk_xfs.h linux-2.4.29-pre3/include/linux/dqblk_xfs.h
--- linux-2.4.28/include/linux/dqblk_xfs.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/include/linux/dqblk_xfs.h	2004-12-22 16:05:30.000000000 +0000
@@ -1,34 +1,22 @@
 /*
- * Copyright (c) 1995-2001 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 1995-2001,2004 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2.1 of the GNU Lesser General Public License
  * as published by the Free Software Foundation.
  *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * 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
  *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like.  Any license provided herein, whether implied or
- * otherwise, applies only to this software file.  Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
- * USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA  94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+ * Mountain View, CA 94043, USA, or: http://www.sgi.com
  */
 #ifndef _LINUX_DQBLK_XFS_H
 #define _LINUX_DQBLK_XFS_H
@@ -40,12 +28,12 @@
  */
 
 #define XQM_CMD(x)	(('X'<<8)+(x))	/* note: forms first QCMD argument */
-#define Q_XQUOTAON	XQM_CMD(0x1)	/* enable accounting/enforcement */
-#define Q_XQUOTAOFF	XQM_CMD(0x2)	/* disable accounting/enforcement */
-#define Q_XGETQUOTA	XQM_CMD(0x3)	/* get disk limits and usage */
-#define Q_XSETQLIM	XQM_CMD(0x4)	/* set disk limits */
-#define Q_XGETQSTAT	XQM_CMD(0x5)	/* get quota subsystem status */
-#define Q_XQUOTARM	XQM_CMD(0x6)	/* free disk space used by dquots */
+#define Q_XQUOTAON	XQM_CMD(1)	/* enable accounting/enforcement */
+#define Q_XQUOTAOFF	XQM_CMD(2)	/* disable accounting/enforcement */
+#define Q_XGETQUOTA	XQM_CMD(3)	/* get disk limits and usage */
+#define Q_XSETQLIM	XQM_CMD(4)	/* set disk limits */
+#define Q_XGETQSTAT	XQM_CMD(5)	/* get quota subsystem status */
+#define Q_XQUOTARM	XQM_CMD(6)	/* free disk space used by dquots */
 
 /*
  * fs_disk_quota structure:
@@ -105,15 +93,30 @@ typedef struct fs_disk_quota {
 #define FS_DQ_TIMER_MASK	(FS_DQ_BTIMER | FS_DQ_ITIMER | FS_DQ_RTBTIMER)
 
 /*
+ * Warning counts are set in both super user's dquot and others. For others,
+ * warnings are set/cleared by the administrators (or automatically by going
+ * below the soft limit).  Superusers warning values set the warning limits
+ * for the rest.  In case these values are zero, the DQ_{F,B}WARNLIMIT values
+ * defined below are used. 
+ * These values also apply only to the d_fieldmask field for Q_XSETQLIM.
+ */
+#define FS_DQ_BWARNS	(1<<9)
+#define FS_DQ_IWARNS	(1<<10)
+#define FS_DQ_RTBWARNS	(1<<11)
+#define FS_DQ_WARNS_MASK	(FS_DQ_BWARNS | FS_DQ_IWARNS | FS_DQ_RTBWARNS)
+
+/*
  * Various flags related to quotactl(2).  Only relevant to XFS filesystems.
  */
 #define XFS_QUOTA_UDQ_ACCT	(1<<0)  /* user quota accounting */
 #define XFS_QUOTA_UDQ_ENFD	(1<<1)  /* user quota limits enforcement */
 #define XFS_QUOTA_GDQ_ACCT	(1<<2)  /* group quota accounting */
 #define XFS_QUOTA_GDQ_ENFD	(1<<3)  /* group quota limits enforcement */
+#define XFS_QUOTA_PDQ_ACCT	(1<<4)  /* project quota accounting */
+#define XFS_QUOTA_PDQ_ENFD	(1<<5)  /* project quota limits enforcement */
 
 #define XFS_USER_QUOTA		(1<<0)	/* user quota type */
-#define XFS_PROJ_QUOTA		(1<<1)	/* (IRIX) project quota type */
+#define XFS_PROJ_QUOTA		(1<<1)	/* project quota type */
 #define XFS_GROUP_QUOTA		(1<<2)	/* group quota type */
 
 /*
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/linux/fb.h linux-2.4.29-pre3/include/linux/fb.h
--- linux-2.4.28/include/linux/fb.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/include/linux/fb.h	2004-12-22 16:06:16.426800688 +0000
@@ -323,6 +323,7 @@ struct fb_info {
    struct fb_cmap cmap;                 /* Current cmap */
    struct fb_ops *fbops;
    char *screen_base;                   /* Virtual address */
+   u32 mapped_vram;			/* ioremap()'ed VRAM */
    struct display *disp;		/* initial display variable */
    struct vc_data *display_fg;		/* Console visible on this display */
    char fontname[40];			/* default font name */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/linux/i2c.h linux-2.4.29-pre3/include/linux/i2c.h
--- linux-2.4.28/include/linux/i2c.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/include/linux/i2c.h	2004-12-22 16:05:54.000000000 +0000
@@ -47,11 +47,9 @@ struct i2c_msg;
 
 /* --- General options ------------------------------------------------	*/
 
-#define I2C_ALGO_MAX	4		/* control memory consumption	*/
-#define I2C_ADAP_MAX	16
+#define I2C_ADAP_MAX	16		/* control memory consumption	*/
 #define I2C_DRIVER_MAX	16
 #define I2C_CLIENT_MAX	32
-#define I2C_DUMMY_MAX 4
 
 struct i2c_algorithm;
 struct i2c_adapter;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/linux/intermezzo_fs.h linux-2.4.29-pre3/include/linux/intermezzo_fs.h
--- linux-2.4.28/include/linux/intermezzo_fs.h	2004-12-22 16:17:21.386711416 +0000
+++ linux-2.4.29-pre3/include/linux/intermezzo_fs.h	2004-12-22 16:06:35.563891408 +0000
@@ -651,6 +651,7 @@ int izo_upc_upcall(int minor, int *size,
 int izo_repstatus(struct presto_file_set *fset, __u64 client_kmlsize, 
                   struct izo_rcvd_rec *lr_client, struct izo_rcvd_rec *lr_server);
 int izo_rep_cache_init(struct presto_file_set *);
+void izo_rep_cache_clean(struct presto_file_set *fset);
 loff_t izo_rcvd_get(struct izo_rcvd_rec *, struct presto_file_set *, char *uuid);
 loff_t izo_rcvd_write(struct presto_file_set *, struct izo_rcvd_rec *);
 loff_t izo_rcvd_upd_remote(struct presto_file_set *fset, char * uuid,  __u64 remote_recno,
@@ -708,10 +709,17 @@ static inline int dentry_name_cmp(struct
 static inline char *strdup(char *str)
 {
         char *tmp;
-        tmp = kmalloc(strlen(str) + 1, GFP_KERNEL);
-        if (tmp)
-                memcpy(tmp, str, strlen(str) + 1);
-               
+		long int s;
+
+		s=strlen(str) + 1;
+        tmp = kmalloc(s, GFP_KERNEL);
+        if (tmp){
+				  memcpy(tmp, str, s);
+				  presto_kmem_inc(tmp, s);
+		}
+        CDEBUG(D_MALLOC, "kmalloced: %ld at %p (tot %ld).\n",
+               s, tmp, presto_kmemory);
+				  
         return tmp;
 }
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/linux/iso_fs.h linux-2.4.29-pre3/include/linux/iso_fs.h
--- linux-2.4.28/include/linux/iso_fs.h	2002-02-25 19:38:13.000000000 +0000
+++ linux-2.4.29-pre3/include/linux/iso_fs.h	2004-12-22 16:07:02.330822216 +0000
@@ -179,28 +179,28 @@ static inline int isonum_712(char *p)
 {
 	return *(s8 *)p;
 }
-static inline int isonum_721(char *p)
+static inline unsigned int isonum_721(char *p)
 {
 	return le16_to_cpu(get_unaligned((u16 *)p));
 }
-static inline int isonum_722(char *p)
+static inline unsigned int isonum_722(char *p)
 {
 	return be16_to_cpu(get_unaligned((u16 *)p));
 }
-static inline int isonum_723(char *p)
+static inline unsigned int isonum_723(char *p)
 {
 	/* Ignore bigendian datum due to broken mastering programs */
 	return le16_to_cpu(get_unaligned((u16 *)p));
 }
-static inline int isonum_731(char *p)
+static inline unsigned int isonum_731(char *p)
 {
 	return le32_to_cpu(get_unaligned((u32 *)p));
 }
-static inline int isonum_732(char *p)
+static inline unsigned int isonum_732(char *p)
 {
 	return be32_to_cpu(get_unaligned((u32 *)p));
 }
-static inline int isonum_733(char *p)
+static inline unsigned int isonum_733(char *p)
 {
 	/* Ignore bigendian datum due to broken mastering programs */
 	return le32_to_cpu(get_unaligned((u32 *)p));
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/linux/istallion.h linux-2.4.29-pre3/include/linux/istallion.h
--- linux-2.4.28/include/linux/istallion.h	1999-09-02 18:22:40.000000000 +0000
+++ linux-2.4.29-pre3/include/linux/istallion.h	2004-12-22 16:05:59.212417672 +0000
@@ -3,7 +3,7 @@
 /*
  *	istallion.h  -- stallion intelligent multiport serial driver.
  *
- *	Copyright (C) 1996-1998  Stallion Technologies (support@stallion.oz.au).
+ *	Copyright (C) 1996-1998  Stallion Technologies
  *	Copyright (C) 1994-1996  Greg Ungerer.
  *
  *	This program is free software; you can redistribute it and/or modify
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/linux/libata-compat.h linux-2.4.29-pre3/include/linux/libata-compat.h
--- linux-2.4.28/include/linux/libata-compat.h	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.29-pre3/include/linux/libata-compat.h	2004-12-22 16:06:37.681569472 +0000
@@ -0,0 +1,50 @@
+#ifndef __LIBATA_COMPAT_H__
+#define __LIBATA_COMPAT_H__
+
+#include <linux/delay.h>
+#include <linux/pci.h>
+
+#define MODULE_VERSION(ver_str)
+
+struct device {
+	struct pci_dev pdev;
+};
+
+static inline void libata_msleep(unsigned long msecs)
+{
+	msleep(msecs);
+}
+
+static inline struct pci_dev *to_pci_dev(struct device *dev)
+{
+	return (struct pci_dev *) dev;
+}
+
+#define pci_set_consistent_dma_mask(pdev,mask) (0)
+
+#define DMA_FROM_DEVICE PCI_DMA_FROMDEVICE
+
+/* NOTE: dangerous! we ignore the 'gfp' argument */
+#define dma_alloc_coherent(dev,sz,dma,gfp) \
+	pci_alloc_consistent(to_pci_dev(dev),(sz),(dma))
+#define dma_free_coherent(dev,sz,addr,dma_addr) \
+	pci_free_consistent(to_pci_dev(dev),(sz),(addr),(dma_addr))
+
+#define dma_map_sg(dev,a,b,c) \
+	pci_map_sg(to_pci_dev(dev),(a),(b),(c))
+#define dma_unmap_sg(dev,a,b,c) \
+	pci_unmap_sg(to_pci_dev(dev),(a),(b),(c))
+
+#define dma_map_single(dev,a,b,c) \
+	pci_map_single(to_pci_dev(dev),(a),(b),(c))
+#define dma_unmap_single(dev,a,b,c) \
+	pci_unmap_single(to_pci_dev(dev),(a),(b),(c))
+
+#define dma_mapping_error(addr) (0)
+
+#define dev_get_drvdata(dev) \
+	pci_get_drvdata(to_pci_dev(dev))
+#define dev_set_drvdata(dev,ptr) \
+	pci_set_drvdata(to_pci_dev(dev),(ptr))
+
+#endif /* __LIBATA_COMPAT_H__ */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/linux/libata.h linux-2.4.29-pre3/include/linux/libata.h
--- linux-2.4.28/include/linux/libata.h	2004-12-22 16:17:21.495694848 +0000
+++ linux-2.4.29-pre3/include/linux/libata.h	2004-12-22 16:07:19.636191400 +0000
@@ -25,9 +25,11 @@
 
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/pci.h>
 #include <asm/io.h>
 #include <linux/ata.h>
 #include <linux/tqueue.h>
+#include <linux/libata-compat.h>
 
 /*
  * compile-time options
@@ -68,6 +70,11 @@
 /* defines only for the constants which don't work well as enums */
 #define ATA_TAG_POISON		0xfafbfcfdU
 
+static inline struct device *pci_dev_to_dev(struct pci_dev *pdev)
+{
+	return (struct device *) pdev;
+}
+
 enum {
 	/* various global constants */
 	LIBATA_MAX_PRD		= ATA_MAX_PRD / 2,
@@ -106,6 +113,7 @@ enum {
 	ATA_FLAG_SRST		= (1 << 5), /* use ATA SRST, not E.D.D. */
 	ATA_FLAG_MMIO		= (1 << 6), /* use MMIO, not PIO */
 	ATA_FLAG_SATA_RESET	= (1 << 7), /* use COMRESET */
+	ATA_FLAG_PIO_DMA	= (1 << 8), /* PIO cmds via DMA */
 
 	ATA_QCFLAG_ACTIVE	= (1 << 1), /* cmd not yet ack'd to scsi lyer */
 	ATA_QCFLAG_SG		= (1 << 3), /* have s/g table? */
@@ -185,7 +193,7 @@ struct ata_ioports {
 
 struct ata_probe_ent {
 	struct list_head	node;
-	struct pci_dev		*pdev;
+	struct device 		*dev;
 	struct ata_port_operations	*port_ops;
 	Scsi_Host_Template	*sht;
 	struct ata_ioports	port[ATA_MAX_PORTS];
@@ -204,7 +212,7 @@ struct ata_probe_ent {
 
 struct ata_host_set {
 	spinlock_t		lock;
-	struct pci_dev		*pdev;
+	struct device 		*dev;
 	unsigned long		irq;
 	void __iomem		*mmio_base;
 	unsigned int		n_ports;
@@ -227,10 +235,14 @@ struct ata_queued_cmd {
 	unsigned int		tag;
 	unsigned int		n_elem;
 
-	int			pci_dma_dir;
+	int			dma_dir;
 
 	unsigned int		nsect;
 	unsigned int		cursect;
+
+	unsigned int		nbytes;
+	unsigned int		curbytes;
+
 	unsigned int		cursg;
 	unsigned int		cursg_ofs;
 
@@ -358,12 +370,6 @@ struct ata_port_info {
 	struct ata_port_operations	*port_ops;
 };
 
-struct pci_bits {
-	unsigned int		reg;	/* PCI config register to read */
-	unsigned int		width;	/* 1 (8 bit), 2 (16 bit), 4 (32 bit) */
-	unsigned long		mask;
-	unsigned long		val;
-};
 
 extern void ata_port_probe(struct ata_port *);
 extern void __sata_phy_reset(struct ata_port *ap);
@@ -371,9 +377,11 @@ extern void sata_phy_reset(struct ata_po
 extern void ata_bus_reset(struct ata_port *ap);
 extern void ata_port_disable(struct ata_port *);
 extern void ata_std_ports(struct ata_ioports *ioaddr);
+#ifdef CONFIG_PCI
 extern int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
 			     unsigned int n_ports);
 extern void ata_pci_remove_one (struct pci_dev *pdev);
+#endif /* CONFIG_PCI */
 extern int ata_device_add(struct ata_probe_ent *ent);
 extern int ata_scsi_detect(Scsi_Host_Template *sht);
 extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
@@ -395,10 +403,6 @@ extern void ata_exec_command(struct ata_
 extern int ata_port_start (struct ata_port *ap);
 extern void ata_port_stop (struct ata_port *ap);
 extern irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
-extern struct ata_probe_ent *
-ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port);
-extern struct ata_probe_ent *
-ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port);
 extern void ata_qc_prep(struct ata_queued_cmd *qc);
 extern int ata_qc_issue_prot(struct ata_queued_cmd *qc);
 extern void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf,
@@ -406,23 +410,35 @@ extern void ata_sg_init_one(struct ata_q
 extern void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
 		 unsigned int n_elem);
 extern unsigned int ata_dev_classify(struct ata_taskfile *tf);
-extern void ata_dev_id_string(struct ata_device *dev, unsigned char *s,
+extern void ata_dev_id_string(u16 *id, unsigned char *s,
 			      unsigned int ofs, unsigned int len);
 extern void ata_bmdma_setup (struct ata_queued_cmd *qc);
 extern void ata_bmdma_start (struct ata_queued_cmd *qc);
 extern void ata_bmdma_irq_clear(struct ata_port *ap);
-extern int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits);
 extern void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat);
 extern void ata_eng_timeout(struct ata_port *ap);
+extern void ata_scsi_simulate(u16 *id, struct scsi_cmnd *cmd,
+			      void (*done)(struct scsi_cmnd *));
 extern void ata_add_to_probe_list (struct ata_probe_ent *probe_ent);
 extern int ata_std_bios_param(Disk * disk, kdev_t dev, int *ip);
-extern void libata_msleep(unsigned long msecs);
 
 
-static inline unsigned long msecs_to_jiffies(unsigned long msecs)
-{
-	return ((HZ * msecs + 999) / 1000);
-}
+#ifdef CONFIG_PCI
+struct pci_bits {
+	unsigned int		reg;	/* PCI config register to read */
+	unsigned int		width;	/* 1 (8 bit), 2 (16 bit), 4 (32 bit) */
+	unsigned long		mask;
+	unsigned long		val;
+};
+
+extern struct ata_probe_ent *
+ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port);
+extern struct ata_probe_ent *
+ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port);
+extern int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits);
+
+#endif /* CONFIG_PCI */
+
 
 static inline unsigned int ata_tag_valid(unsigned int tag)
 {
@@ -620,9 +636,9 @@ static inline u8 ata_bmdma_status(struct
 
 static inline int ata_try_flush_cache(struct ata_device *dev)
 {
-	return ata_id_wcache_enabled(dev) ||
-	       ata_id_has_flush(dev) ||
-	       ata_id_has_flush_ext(dev);
+	return ata_id_wcache_enabled(dev->id) ||
+	       ata_id_has_flush(dev->id) ||
+	       ata_id_has_flush_ext(dev->id);
 }
 
 #endif /* __LINUX_LIBATA_H__ */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/linux/mii.h linux-2.4.29-pre3/include/linux/mii.h
--- linux-2.4.28/include/linux/mii.h	2002-11-28 23:53:15.000000000 +0000
+++ linux-2.4.29-pre3/include/linux/mii.h	2004-12-22 16:05:31.000000000 +0000
@@ -9,6 +9,7 @@
 #define __LINUX_MII_H__
 
 #include <linux/types.h>
+#include <linux/if.h>
 
 /* Generic MII registers. */
 
@@ -144,6 +145,12 @@ struct mii_ioctl_data {
 };
 
 
+static inline struct mii_ioctl_data *if_mii(struct ifreq *rq)
+{
+	return (struct mii_ioctl_data *) &rq->ifr_ifru;
+}
+
+
 /**
  * mii_nway_result
  * @negotiated: value of MII ANAR and'd with ANLPAR
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/linux/mm.h linux-2.4.29-pre3/include/linux/mm.h
--- linux-2.4.28/include/linux/mm.h	2004-12-22 16:17:21.593679952 +0000
+++ linux-2.4.29-pre3/include/linux/mm.h	2004-12-22 16:05:32.000000000 +0000
@@ -199,6 +199,11 @@ typedef struct page {
 #define page_count(p)		atomic_read(&(p)->count)
 #define set_page_count(p,v) 	atomic_set(&(p)->count, v)
 
+static inline struct page *nth_page(struct page *page, int n)
+{
+	return page + n;
+}
+
 /*
  * Various page->flags bits:
  *
@@ -543,7 +548,7 @@ extern void __free_pte(pte_t);
 /* mmap.c */
 extern void lock_vma_mappings(struct vm_area_struct *);
 extern void unlock_vma_mappings(struct vm_area_struct *);
-extern void insert_vm_struct(struct mm_struct *, struct vm_area_struct *);
+extern int insert_vm_struct(struct mm_struct *, struct vm_area_struct *);
 extern void __insert_vm_struct(struct mm_struct *, struct vm_area_struct *);
 extern void build_mmap_rb(struct mm_struct *);
 extern void exit_mmap(struct mm_struct *);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/linux/netlink.h linux-2.4.29-pre3/include/linux/netlink.h
--- linux-2.4.28/include/linux/netlink.h	2004-08-07 23:26:06.000000000 +0000
+++ linux-2.4.29-pre3/include/linux/netlink.h	2004-12-22 16:07:32.387252944 +0000
@@ -113,6 +113,7 @@ extern void netlink_broadcast(struct soc
 extern void netlink_set_err(struct sock *ssk, __u32 pid, __u32 group, int code);
 extern int netlink_register_notifier(struct notifier_block *nb);
 extern int netlink_unregister_notifier(struct notifier_block *nb);
+extern int netlink_proto_init(void);
 
 /*
  *	skb should fit one page. This choice is good for headerless malloc.
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/linux/pci_ids.h linux-2.4.29-pre3/include/linux/pci_ids.h
--- linux-2.4.28/include/linux/pci_ids.h	2004-12-22 16:17:21.705662928 +0000
+++ linux-2.4.29-pre3/include/linux/pci_ids.h	2004-12-22 16:06:30.249699288 +0000
@@ -303,6 +303,7 @@
 #define PCI_DEVICE_ID_ATI_RADEON_NI	0x4e49
 /* Radeon RV350 (9600) */
 #define PCI_DEVICE_ID_ATI_RADEON_AP	0x4150
+#define PCI_DEVICE_ID_ATI_RADEON_AQ	0x4151
 #define PCI_DEVICE_ID_ATI_RADEON_AR	0x4152
 /* Radeon M6 */
 #define PCI_DEVICE_ID_ATI_RADEON_LY	0x4c59
@@ -981,24 +982,34 @@
 #define PCI_DEVICE_ID_NVIDIA_UVTNT2		0x002D
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE	0x0035
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA	0x0036
+#define PCI_DEVICE_ID_NVIDIA_NVENET_10		0x0037
+#define PCI_DEVICE_ID_NVIDIA_NVENET_11		0x0038
 #define PCI_DEVICE_ID_NVIDIA_MCP04_AUDIO	0x003a
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2	0x003e
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE	0x0053
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA	0x0054
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2	0x0055
+#define PCI_DEVICE_ID_NVIDIA_NVENET_8		0x0056
+#define PCI_DEVICE_ID_NVIDIA_NVENET_9		0x0057
 #define PCI_DEVICE_ID_NVIDIA_CK804_AUDIO	0x0059
 #define PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE	0x0065
+#define PCI_DEVICE_ID_NVIDIA_NVENET_2		0x0066
 #define PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO		0x006a
 #define PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE	0x0085
+#define PCI_DEVICE_ID_NVIDIA_NVENET_4		0x0086
+#define PCI_DEVICE_ID_NVIDIA_NVENET_5		0x008c
 #define PCI_DEVICE_ID_NVIDIA_MCP2S_AUDIO	0x008a
 #define PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA	0x008e
 #define PCI_DEVICE_ID_NVIDIA_ITNT2		0x00A0
 #define PCI_DEVICE_ID_NVIDIA_NFORCE3		0x00d1
 #define PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE	0x00d5
+#define PCI_DEVICE_ID_NVIDIA_NVENET_3		0x00d6
 #define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO		0x00da
+#define PCI_DEVICE_ID_NVIDIA_NVENET_7		0x00df
 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S		0x00e1
 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA	0x00e3
 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE	0x00e5
+#define PCI_DEVICE_ID_NVIDIA_NVENET_6		0x00e6
 #define PCI_DEVICE_ID_NVIDIA_CK8S_AUDIO		0x00ea
 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2	0x00ee
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR	0x0100
@@ -1016,6 +1027,7 @@
 #define PCI_DEVICE_ID_NVIDIA_NFORCE		0x01a4
 #define PCI_DEVICE_ID_NVIDIA_MCP1_AUDIO		0x01b1
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_IDE		0x01bc
+#define PCI_DEVICE_ID_NVIDIA_NVENET_1		0x01c3
 #define PCI_DEVICE_ID_NVIDIA_NFORCE2		0x01e0
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE3		0x0200
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE3_1		0x0201
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/linux/proc_fs.h linux-2.4.29-pre3/include/linux/proc_fs.h
--- linux-2.4.28/include/linux/proc_fs.h	2004-12-22 16:17:21.719660800 +0000
+++ linux-2.4.29-pre3/include/linux/proc_fs.h	2004-12-22 16:05:31.000000000 +0000
@@ -144,6 +144,8 @@ extern struct proc_dir_entry *proc_symli
 extern struct proc_dir_entry *proc_mknod(const char *,mode_t,
 		struct proc_dir_entry *,kdev_t);
 extern struct proc_dir_entry *proc_mkdir(const char *,struct proc_dir_entry *);
+extern struct proc_dir_entry *proc_mkdir_mode(const char *name, mode_t mode,
+			struct proc_dir_entry *parent);
 
 static inline struct proc_dir_entry *create_proc_read_entry(const char *name,
 	mode_t mode, struct proc_dir_entry *base, 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/linux/sc26198.h linux-2.4.29-pre3/include/linux/sc26198.h
--- linux-2.4.28/include/linux/sc26198.h	1998-02-04 22:52:16.000000000 +0000
+++ linux-2.4.29-pre3/include/linux/sc26198.h	2004-12-22 16:06:38.590431304 +0000
@@ -3,7 +3,7 @@
 /*
  *	sc26198.h  -- SC26198 UART hardware info.
  *
- *	Copyright (C) 1995-1998  Stallion Technologies (support@stallion.oz.au).
+ *	Copyright (C) 1995-1998  Stallion Technologies
  *
  *	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
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/linux/scc.h linux-2.4.29-pre3/include/linux/scc.h
--- linux-2.4.28/include/linux/scc.h	2001-04-12 19:20:31.000000000 +0000
+++ linux-2.4.29-pre3/include/linux/scc.h	2004-12-22 16:07:11.193474888 +0000
@@ -200,7 +200,7 @@ struct scc_kiss {
 	unsigned char fulldup;		/* Full Duplex mode 0=CSMA 1=DUP 2=ALWAYS KEYED */
 	unsigned char waittime;		/* Waittime before any transmit attempt */
 	unsigned int  maxkeyup;		/* Maximum time to transmit (seconds) */
-	unsigned char mintime;		/* Minimal offtime after MAXKEYUP timeout (seconds) */
+	unsigned int  mintime;		/* Minimal offtime after MAXKEYUP timeout (seconds) */
 	unsigned int  idletime;		/* Maximum idle time in ALWAYS KEYED mode (seconds) */
 	unsigned int  maxdefer;		/* Timer for CSMA channel busy limit */
 	unsigned char tx_inhibit;	/* Transmit is not allowed when set */	
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/linux/sched.h linux-2.4.29-pre3/include/linux/sched.h
--- linux-2.4.28/include/linux/sched.h	2004-12-22 16:17:21.783651072 +0000
+++ linux-2.4.29-pre3/include/linux/sched.h	2004-12-22 16:05:43.000000000 +0000
@@ -800,6 +800,9 @@ extern void daemonize(void);
 extern int do_execve(char *, char **, char **, struct pt_regs *);
 extern int do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long);
 
+extern void set_task_comm(struct task_struct *tsk, char *from);
+extern void get_task_comm(char *to, struct task_struct *tsk);
+
 extern void FASTCALL(add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait));
 extern void FASTCALL(add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t * wait));
 extern void FASTCALL(remove_wait_queue(wait_queue_head_t *q, wait_queue_t * wait));
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/linux/socket.h linux-2.4.29-pre3/include/linux/socket.h
--- linux-2.4.28/include/linux/socket.h	2004-12-22 16:17:21.795649248 +0000
+++ linux-2.4.29-pre3/include/linux/socket.h	2004-12-22 16:07:20.605044112 +0000
@@ -87,6 +87,10 @@ struct cmsghdr {
 				  (struct cmsghdr *)(ctl) : \
 				  (struct cmsghdr *)NULL)
 #define CMSG_FIRSTHDR(msg)	__CMSG_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
+#define CMSG_OK(mhdr, cmsg) ((cmsg)->cmsg_len >= sizeof(struct cmsghdr) && \
+			     (cmsg)->cmsg_len <= (unsigned long) \
+			     ((mhdr)->msg_controllen - \
+			      ((char *)(cmsg) - (char *)(mhdr)->msg_control)))
 
 /*
  *	This mess will go away with glibc
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/linux/stallion.h linux-2.4.29-pre3/include/linux/stallion.h
--- linux-2.4.28/include/linux/stallion.h	2000-12-05 20:31:01.000000000 +0000
+++ linux-2.4.29-pre3/include/linux/stallion.h	2004-12-22 16:07:33.036154296 +0000
@@ -3,7 +3,7 @@
 /*
  *	stallion.h  -- stallion multiport serial driver.
  *
- *	Copyright (C) 1996-1998  Stallion Technologies (support@stallion.oz.au).
+ *	Copyright (C) 1996-1998  Stallion Technologies
  *	Copyright (C) 1994-1996  Greg Ungerer.
  *
  *	This program is free software; you can redistribute it and/or modify
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/linux/swap.h linux-2.4.29-pre3/include/linux/swap.h
--- linux-2.4.28/include/linux/swap.h	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/include/linux/swap.h	2004-12-22 16:05:32.000000000 +0000
@@ -116,7 +116,7 @@ extern void swap_setup(void);
 extern wait_queue_head_t kswapd_wait;
 extern int FASTCALL(try_to_free_pages_zone(zone_t *, unsigned int));
 extern int FASTCALL(try_to_free_pages(unsigned int));
-extern int vm_vfs_scan_ratio, vm_cache_scan_ratio, vm_lru_balance_ratio, vm_passes, vm_gfp_debug, vm_mapped_ratio;
+extern int vm_vfs_scan_ratio, vm_cache_scan_ratio, vm_lru_balance_ratio, vm_passes, vm_gfp_debug, vm_mapped_ratio, vm_anon_lru;
 
 /* linux/mm/page_io.c */
 extern void rw_swap_page(int, struct page *);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/linux/sysctl.h linux-2.4.29-pre3/include/linux/sysctl.h
--- linux-2.4.28/include/linux/sysctl.h	2004-08-07 23:26:06.000000000 +0000
+++ linux-2.4.29-pre3/include/linux/sysctl.h	2004-12-22 16:05:31.000000000 +0000
@@ -154,9 +154,10 @@ enum
 	VM_PAGEBUF=17,		/* struct: Control pagebuf parameters */
 	VM_GFP_DEBUG=18,        /* debug GFP failures */
 	VM_CACHE_SCAN_RATIO=19, /* part of the inactive cache list to scan */
-	VM_MAPPED_RATIO=20,     /* amount of unfreeable pages that triggers swapout */
+	VM_MAPPED_RATIO=20,	/* amount of unfreeable pages that triggers swapout */
 	VM_LAPTOP_MODE=21,	/* kernel in laptop flush mode */
 	VM_BLOCK_DUMP=22,	/* dump fs activity to log */
+	VM_ANON_LRU=23,		/* immediatly insert anon pages in the vm page lru */
 };
 
 
@@ -627,7 +628,7 @@ enum
 	FS_LEASES=13,	/* int: leases enabled */
 	FS_DIR_NOTIFY=14,	/* int: directory notification enabled */
 	FS_LEASE_TIME=15,	/* int: maximum time to wait for a lease break */
-	FS_DQSTATS=16,	/* dir: disc quota usage statistics */
+	FS_DQSTATS=16,	/* dir: disc quota usage statistics and settings */
 	FS_XFS=17,	/* struct: control xfs parameters */
 };
 
@@ -641,6 +642,7 @@ enum {
 	FS_DQ_ALLOCATED = 6,
 	FS_DQ_FREE = 7,
 	FS_DQ_SYNCS = 8,
+	FS_DQ_WARNINGS = 9,
 };
 
 /* CTL_DEBUG names: */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/linux/tty.h linux-2.4.29-pre3/include/linux/tty.h
--- linux-2.4.28/include/linux/tty.h	2003-06-13 14:51:39.000000000 +0000
+++ linux-2.4.29-pre3/include/linux/tty.h	2004-12-22 16:06:45.438390256 +0000
@@ -260,6 +260,7 @@ struct tty_struct {
 	int	magic;
 	struct tty_driver driver;
 	struct tty_ldisc ldisc;
+	struct semaphore termios_sem;
 	struct termios *termios, *termios_locked;
 	int pgrp;
 	int session;
@@ -322,26 +323,28 @@ struct tty_struct {
  * tty->write.  Thus, you must use the inline functions set_bit() and
  * clear_bit() to make things atomic.
  */
-#define TTY_THROTTLED 0
-#define TTY_IO_ERROR 1
-#define TTY_OTHER_CLOSED 2
-#define TTY_EXCLUSIVE 3
-#define TTY_DEBUG 4
-#define TTY_DO_WRITE_WAKEUP 5
-#define TTY_PUSH 6
-#define TTY_CLOSING 7
-#define TTY_DONT_FLIP 8
-#define TTY_HW_COOK_OUT 14
-#define TTY_HW_COOK_IN 15
-#define TTY_PTY_LOCK 16
-#define TTY_NO_WRITE_SPLIT 17
+#define TTY_THROTTLED 		0	/* Call unthrottle() at threshold min */
+#define TTY_IO_ERROR 		1	/* Canse an I/O error (may be no ldisc too) */
+#define TTY_OTHER_CLOSED 	2	/* Other side (if any) has closed */
+#define TTY_EXCLUSIVE 		3	/* Exclusive open mode */
+#define TTY_DEBUG 		4	/* Debugging */
+#define TTY_DO_WRITE_WAKEUP 	5	/* Call write_wakeup after queuing new */
+#define TTY_PUSH 		6	/* n_tty private */
+#define TTY_CLOSING 		7	/* ->close() in progress */
+#define TTY_DONT_FLIP 		8	/* Defer buffer flip */
+#define TTY_LDISC 		9	/* Line discipline attached */
+#define TTY_HW_COOK_OUT 	14	/* Hardware can do output cooking */
+#define TTY_HW_COOK_IN 	15	/* Hardware can do input cooking */
+#define TTY_PTY_LOCK 		16	/* pty private */
+#define TTY_NO_WRITE_SPLIT 	17	/* Preserve write boundaries to driver */
+#define TTY_HUPPED 		18	/* Post driver->hangup() */
 
 #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty))
 
 extern void tty_write_flush(struct tty_struct *);
 
 extern struct termios tty_std_termios;
-extern struct tty_ldisc ldiscs[];
+extern struct tty_ldisc tty_ldiscs[];
 extern int fg_console, last_console, want_console;
 
 extern int kmsg_redirect;
@@ -396,6 +399,17 @@ extern void disassociate_ctty(int priv);
 extern void tty_flip_buffer_push(struct tty_struct *tty);
 extern int tty_get_baud_rate(struct tty_struct *tty);
 
+extern struct tty_ldisc *tty_ldisc_ref(struct tty_struct *);
+extern void tty_ldisc_deref(struct tty_ldisc *);
+extern struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *);
+
+extern struct tty_ldisc *tty_ldisc_get(int);
+extern void tty_ldisc_put(int);
+
+extern void tty_wakeup(struct tty_struct *tty);
+extern void tty_ldisc_flush(struct tty_struct *tty);
+
+
 /* n_tty.c */
 extern struct tty_ldisc tty_ldisc_N_TTY;
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/linux/tty_ldisc.h linux-2.4.29-pre3/include/linux/tty_ldisc.h
--- linux-2.4.28/include/linux/tty_ldisc.h	2001-11-22 19:46:19.000000000 +0000
+++ linux-2.4.29-pre3/include/linux/tty_ldisc.h	2004-12-22 16:07:52.230236352 +0000
@@ -95,6 +95,13 @@
  * 	that line discpline should try to send more characters to the
  * 	low-level driver for transmission.  If the line discpline does
  * 	not have any more data to send, it can just return.
+ *
+ * int (*hangup)(struct tty_struct *)
+ *
+ *	Called on a hangup. Tells the discipline that it should
+ *	cease I/O to the tty driver. Can sleep. The driver should
+ *	seek to perform this action quickly but should wait until
+ *	any pending driver I/O is completed.
  */
 
 #include <linux/fs.h>
@@ -121,6 +128,7 @@ struct tty_ldisc {
 	void	(*set_termios)(struct tty_struct *tty, struct termios * old);
 	unsigned int (*poll)(struct tty_struct *, struct file *,
 			     struct poll_table_struct *);
+	int     (*hangup)(struct tty_struct *tty);
 	
 	/*
 	 * The following routines are called from below.
@@ -129,6 +137,7 @@ struct tty_ldisc {
 			       char *fp, int count);
 	int	(*receive_room)(struct tty_struct *);
 	void	(*write_wakeup)(struct tty_struct *);
+	int	refcount;
 };
 
 #define TTY_LDISC_MAGIC	0x5403
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/linux/usb_ch9.h linux-2.4.29-pre3/include/linux/usb_ch9.h
--- linux-2.4.28/include/linux/usb_ch9.h	2004-08-07 23:26:06.000000000 +0000
+++ linux-2.4.29-pre3/include/linux/usb_ch9.h	2004-12-22 16:06:32.586344064 +0000
@@ -79,6 +79,7 @@
 #define USB_DEVICE_B_HNP_ENABLE		3	/* dev may initiate HNP */
 #define USB_DEVICE_A_HNP_SUPPORT	4	/* RH port supports HNP */
 #define USB_DEVICE_A_ALT_HNP_SUPPORT	5	/* other RH port does */
+#define USB_DEVICE_DEBUG_MODE		6	/* (special devices only) */
 
 #define USB_ENDPOINT_HALT		0	/* IN/OUT will STALL */
 
@@ -323,6 +324,18 @@ struct usb_otg_descriptor {
 
 /*-------------------------------------------------------------------------*/
 
+/* USB_DT_DEBUG:  for special highspeed devices, replacing serial console */
+struct usb_debug_descriptor {
+	__u8  bLength;
+	__u8  bDescriptorType;
+
+	/* bulk endpoints with 8 byte maxpacket */
+	__u8  bDebugInEndpoint;
+	__u8  bDebugOutEndpoint;
+};
+
+/*-------------------------------------------------------------------------*/
+
 /* USB_DT_INTERFACE_ASSOCIATION: groups interfaces */
 struct usb_interface_assoc_descriptor {
 	__u8  bLength;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/linux/usb_gadget.h linux-2.4.29-pre3/include/linux/usb_gadget.h
--- linux-2.4.28/include/linux/usb_gadget.h	2004-08-07 23:26:06.000000000 +0000
+++ linux-2.4.29-pre3/include/linux/usb_gadget.h	2004-12-22 16:06:00.693192560 +0000
@@ -6,7 +6,7 @@
  * master many USB gadgets, but the gadgets are only slaved to one host.
  *
  *
- * (c) Copyright 2002-2003 by David Brownell
+ * (C) Copyright 2002-2004 by David Brownell
  * All Rights Reserved.
  *
  * This software is licensed under the GNU GPL version 2.
@@ -73,8 +73,6 @@ struct usb_ep;
  */
 	// NOTE this is analagous to 'struct urb' on the host side,
 	// except that it's thinner and promotes more pre-allocation.
-	//
-	// ISSUE should this be allocated through the device?
 
 struct usb_request {
 	void			*buf;
@@ -116,8 +114,8 @@ struct usb_ep_ops {
 		dma_addr_t *dma, int gfp_flags);
 	void (*free_buffer) (struct usb_ep *ep, void *buf, dma_addr_t dma,
 		unsigned bytes);
-	// NOTE:  on 2.5, drivers may also use dma_map() and
-	// dma_sync_single() to manage dma overhead. 
+	// NOTE:  on 2.6, drivers may also use dma_map() and
+	// dma_sync_single_*() to directly manage dma overhead. 
 
 	int (*queue) (struct usb_ep *ep, struct usb_request *req,
 		int gfp_flags);
@@ -453,7 +451,10 @@ struct usb_gadget;
 struct usb_gadget_ops {
 	int	(*get_frame)(struct usb_gadget *);
 	int	(*wakeup)(struct usb_gadget *);
-	int	(*set_selfpowered) (struct usb_gadget *, int value);
+	int	(*set_selfpowered) (struct usb_gadget *, int is_selfpowered);
+	int	(*vbus_session) (struct usb_gadget *, int is_active);
+	int	(*vbus_draw) (struct usb_gadget *, unsigned mA);
+	int	(*pullup) (struct usb_gadget *, int is_on);
 	int	(*ioctl)(struct usb_gadget *,
 				unsigned code, unsigned long param);
 };
@@ -467,6 +468,17 @@ struct usb_gadget_ops {
  * @speed: Speed of current connection to USB host.
  * @is_dualspeed: True if the controller supports both high and full speed
  *	operation.  If it does, the gadget driver must also support both.
+ * @is_otg: True if the USB device port uses a Mini-AB jack, so that the
+ *	gadget driver must provide a USB OTG descriptor.
+ * @is_a_peripheral: False unless is_otg, the "A" end of a USB cable
+ *	is in the Mini-AB jack, and HNP has been used to switch roles
+ *	so that the "A" device currently acts as A-Peripheral, not A-Host.
+ * @a_hnp_support: OTG device feature flag, indicating that the A-Host
+ *	supports HNP at this port.
+ * @a_alt_hnp_support: OTG device feature flag, indicating that the A-Host
+ *	only supports HNP on a different root port.
+ * @b_hnp_enable: OTG device feature flag, indicating that the A-Host
+ *	enabled HNP support.
  * @name: Identifies the controller hardware type.  Used in diagnostics
  * 	and sometimes configuration.
  * @dev: Driver model state for this abstract device.
@@ -480,9 +492,14 @@ struct usb_gadget_ops {
  *
  * Except for the driver data, all fields in this structure are
  * read-only to the gadget driver.  That driver data is part of the
- * "driver model" infrastructure in 2.5 (and later) kernels, and for
+ * "driver model" infrastructure in 2.6 (and later) kernels, and for
  * earlier systems is grouped in a similar structure that's not known
  * to the rest of the kernel.
+ *
+ * Values of the three OTG device feature flags are updated before the
+ * setup() call corresponding to USB_REQ_SET_CONFIGURATION, and before
+ * driver suspend() calls.  They are valid only when is_otg, and when the
+ * device is acting as a B-Peripheral (so is_a_peripheral is false).
  */
 struct usb_gadget {
 	/* readonly to gadget driver */
@@ -491,6 +508,11 @@ struct usb_gadget {
 	struct list_head		ep_list;	/* of usb_ep */
 	enum usb_device_speed		speed;
 	unsigned			is_dualspeed:1;
+	unsigned			is_otg:1;
+	unsigned			is_a_peripheral:1;
+	unsigned			b_hnp_enable:1;
+	unsigned			a_hnp_support:1;
+	unsigned			a_alt_hnp_support:1;
 	const char			*name;
 
 	struct __gadget_device {
@@ -540,6 +562,10 @@ static inline int usb_gadget_frame_numbe
  * doesn't support such attempts, or its support has not been enabled
  * by the usb host.  Drivers must return device descriptors that report
  * their ability to support this, or hosts won't enable it.
+ *
+ * This may also try to use SRP to wake the host and start enumeration,
+ * even if OTG isn't otherwise in use.  OTG devices may also start
+ * remote wakeup even when hosts don't explicitly enable it.
  */
 static inline int usb_gadget_wakeup (struct usb_gadget *gadget)
 {
@@ -583,6 +609,107 @@ usb_gadget_clear_selfpowered (struct usb
 	return gadget->ops->set_selfpowered (gadget, 0);
 }
 
+/**
+ * usb_gadget_vbus_connect - Notify controller that VBUS is powered
+ * @gadget:The device which now has VBUS power.
+ *
+ * This call is used by a driver for an external transceiver (or GPIO)
+ * that detects a VBUS power session starting.  Common responses include
+ * resuming the controller, activating the D+ (or D-) pullup to let the
+ * host detect that a USB device is attached, and starting to draw power
+ * (8mA or possibly more, especially after SET_CONFIGURATION).
+ *
+ * Returns zero on success, else negative errno.
+ */
+static inline int
+usb_gadget_vbus_connect(struct usb_gadget *gadget)
+{
+	if (!gadget->ops->vbus_session)
+		return -EOPNOTSUPP;
+	return gadget->ops->vbus_session (gadget, 1);
+}
+
+/**
+ * usb_gadget_vbus_draw - constrain controller's VBUS power usage
+ * @gadget:The device whose VBUS usage is being described
+ * @mA:How much current to draw, in milliAmperes.  This should be twice
+ *	the value listed in the configuration descriptor bMaxPower field.
+ *
+ * This call is used by gadget drivers during SET_CONFIGURATION calls,
+ * reporting how much power the device may consume.  For example, this
+ * could affect how quickly batteries are recharged.
+ *
+ * Returns zero on success, else negative errno.
+ */
+static inline int
+usb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA)
+{
+	if (!gadget->ops->vbus_draw)
+		return -EOPNOTSUPP;
+	return gadget->ops->vbus_draw (gadget, mA);
+}
+
+/**
+ * usb_gadget_vbus_disconnect - notify controller about VBUS session end
+ * @gadget:the device whose VBUS supply is being described
+ *
+ * This call is used by a driver for an external transceiver (or GPIO)
+ * that detects a VBUS power session ending.  Common responses include
+ * reversing everything done in usb_gadget_vbus_connect().
+ *
+ * Returns zero on success, else negative errno.
+ */
+static inline int
+usb_gadget_vbus_disconnect(struct usb_gadget *gadget)
+{
+	if (!gadget->ops->vbus_session)
+		return -EOPNOTSUPP;
+	return gadget->ops->vbus_session (gadget, 0);
+}
+
+/**
+ * usb_gadget_connect - software-controlled connect to USB host
+ * @gadget:the peripheral being connected
+ *
+ * Enables the D+ (or potentially D-) pullup.  The host will start
+ * enumerating this gadget when the pullup is active and a VBUS session
+ * is active (the link is powered).  This pullup is always enabled unless
+ * usb_gadget_disconnect() has been used to disable it.
+ *
+ * Returns zero on success, else negative errno.
+ */
+static inline int
+usb_gadget_connect (struct usb_gadget *gadget)
+{
+	if (!gadget->ops->pullup)
+		return -EOPNOTSUPP;
+	return gadget->ops->pullup (gadget, 1);
+}
+
+/**
+ * usb_gadget_disconnect - software-controlled disconnect from USB host
+ * @gadget:the peripheral being disconnected
+ *
+ * Disables the D+ (or potentially D-) pullup, which the host may see
+ * as a disconnect (when a VBUS session is active).  Not all systems
+ * support software pullup controls.
+ *
+ * This routine may be used during the gadget driver bind() call to prevent
+ * the peripheral from ever being visible to the USB host, unless later
+ * usb_gadget_connect() is called.  For example, user mode components may
+ * need to be activated before the system can talk to hosts.
+ *
+ * Returns zero on success, else negative errno.
+ */
+static inline int
+usb_gadget_disconnect (struct usb_gadget *gadget)
+{
+	if (!gadget->ops->pullup)
+		return -EOPNOTSUPP;
+	return gadget->ops->pullup (gadget, 0);
+}
+
+
 
 /*-------------------------------------------------------------------------*/
 
@@ -610,11 +737,18 @@ usb_gadget_clear_selfpowered (struct usb
  * 	Called in a context that permits sleeping.
  * @suspend: Invoked on USB suspend.  May be called in_interrupt.
  * @resume: Invoked on USB resume.  May be called in_interrupt.
+ * @driver: Driver model state for this driver.
  *
  * Devices are disabled till a gadget driver successfully bind()s, which
  * means the driver will handle setup() requests needed to enumerate (and
  * meet "chapter 9" requirements) then do some useful work.
  *
+ * If gadget->is_otg is true, the gadget driver must provide an OTG
+ * descriptor during enumeration, or else fail the bind() call.  In such
+ * cases, no USB traffic may flow until both bind() returns without
+ * having called usb_gadget_disconnect(), and the USB host stack has
+ * initialized.
+ *
  * Drivers use hardware-specific knowledge to configure the usb hardware.
  * endpoint addressing is only one of several hardware characteristics that
  * are in descriptors the ep0 implementation returns from setup() calls.
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/net/ip_vs.h linux-2.4.29-pre3/include/net/ip_vs.h
--- linux-2.4.28/include/net/ip_vs.h	2004-12-22 16:17:21.829644080 +0000
+++ linux-2.4.29-pre3/include/net/ip_vs.h	2004-12-22 16:07:12.007351160 +0000
@@ -317,6 +317,7 @@ enum {
 	NET_IPV4_VS_EXPIRE_NODEST_CONN=23,
 	NET_IPV4_VS_SYNC_THRESHOLD=24,
 	NET_IPV4_VS_NAT_ICMP_SEND=25,
+	NET_IPV4_VS_EXPIRE_QUIESCENT_TEMPLATE=26,
 	NET_IPV4_VS_LAST
 };
 
@@ -700,6 +701,7 @@ extern void ip_vs_scheduler_put(struct i
  */
 extern int sysctl_ip_vs_cache_bypass;
 extern int sysctl_ip_vs_expire_nodest_conn;
+extern int sysctl_ip_vs_expire_quiescent_template;
 extern int sysctl_ip_vs_sync_threshold;
 extern int sysctl_ip_vs_nat_icmp_send;
 extern struct ip_vs_stats ip_vs_stats;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/include/net/udp.h linux-2.4.29-pre3/include/net/udp.h
--- linux-2.4.28/include/net/udp.h	2001-11-22 19:47:15.000000000 +0000
+++ linux-2.4.29-pre3/include/net/udp.h	2004-12-22 16:07:21.315936040 +0000
@@ -23,6 +23,7 @@
 #define _UDP_H
 
 #include <linux/udp.h>
+#include <linux/poll.h>
 #include <net/sock.h>
 
 #define UDP_HTABLE_SIZE		128
@@ -68,6 +69,8 @@ extern int	udp_sendmsg(struct sock *sk, 
 extern int	udp_rcv(struct sk_buff *skb);
 extern int	udp_ioctl(struct sock *sk, int cmd, unsigned long arg);
 extern int	udp_disconnect(struct sock *sk, int flags);
+extern unsigned int udp_poll(struct file *file, struct socket *sock,
+			     poll_table *wait);
 
 extern struct udp_mib udp_statistics[NR_CPUS*2];
 #define UDP_INC_STATS(field)		SNMP_INC_STATS(udp_statistics, field)
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/init/do_mounts.c linux-2.4.29-pre3/init/do_mounts.c
--- linux-2.4.28/init/do_mounts.c	2003-11-28 18:26:21.000000000 +0000
+++ linux-2.4.29-pre3/init/do_mounts.c	2004-12-22 16:07:32.366256136 +0000
@@ -348,6 +348,7 @@ static void __init mount_block_root(char
 {
 	char *fs_names = __getname();
 	char *p;
+	int tries = 10;
 
 	get_fs_names(fs_names);
 retry:
@@ -367,11 +368,18 @@ retry:
 		 * Allow the user to distinguish between failed open
 		 * and bad superblock on root device.
 		 */
+		if (--tries) {
+			printk ("VFS: Cannot open root device \"%s\" or %s, "
+				"retrying in 1s.\n",
+				root_device_name, kdevname (ROOT_DEV));
+			set_current_state(TASK_UNINTERRUPTIBLE);
+			schedule_timeout(HZ);
+			goto retry;
+		}
 		printk ("VFS: Cannot open root device \"%s\" or %s\n",
 			root_device_name, kdevname (ROOT_DEV));
 		printk ("Please append a correct \"root=\" boot option\n");
-		panic("VFS: Unable to mount root fs on %s",
-			kdevname(ROOT_DEV));
+		break;
 	}
 	panic("VFS: Unable to mount root fs on %s", kdevname(ROOT_DEV));
 out:
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/kernel/fork.c linux-2.4.29-pre3/kernel/fork.c
--- linux-2.4.28/kernel/fork.c	2004-12-22 16:17:23.870333848 +0000
+++ linux-2.4.29-pre3/kernel/fork.c	2004-12-22 16:05:43.000000000 +0000
@@ -513,8 +513,17 @@ static int copy_files(unsigned long clon
 
 	for (i = open_files; i != 0; i--) {
 		struct file *f = *old_fds++;
-		if (f)
+		if (f) {
 			get_file(f);
+		} else {
+			/*
+			 * The fd may be claimed in the fd bitmap but not yet
+			 * instantiated in the files array if a sibling thread
+			 * is partway through open().  So make sure that this
+			 * fd is available to the new process.
+			 */
+                        FD_CLR(open_files - i, newf->open_fds);
+		}
 		*new_fds++ = f;
 	}
 	read_unlock(&oldf->file_lock);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/kernel/sysctl.c linux-2.4.29-pre3/kernel/sysctl.c
--- linux-2.4.28/kernel/sysctl.c	2004-12-22 16:17:23.898329592 +0000
+++ linux-2.4.29-pre3/kernel/sysctl.c	2004-12-22 16:05:44.000000000 +0000
@@ -290,6 +290,8 @@ static ctl_table vm_table[] = {
 	 &vm_cache_scan_ratio, sizeof(int), 0644, NULL, &proc_dointvec},
 	{VM_MAPPED_RATIO, "vm_mapped_ratio", 
 	 &vm_mapped_ratio, sizeof(int), 0644, NULL, &proc_dointvec},
+	{VM_ANON_LRU, "vm_anon_lru", 
+	 &vm_anon_lru, sizeof(int), 0644, NULL, &proc_dointvec},
 	{VM_LRU_BALANCE_RATIO, "vm_lru_balance_ratio", 
 	 &vm_lru_balance_ratio, sizeof(int), 0644, NULL, &proc_dointvec},
 	{VM_PASSES, "vm_passes", 
@@ -377,6 +379,9 @@ int do_sysctl(int *name, int nlen, void 
 		int old_len;
 		if (!oldlenp || get_user(old_len, oldlenp))
 			return -EFAULT;
+		/* XXX: insufficient for SMP, but should be redundant anyway */
+		if ((ssize_t)old_len < 0)
+			return -EINVAL;
 	}
 	tmp = &root_table_header.ctl_entry;
 	do {
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/lib/rwsem-spinlock.c linux-2.4.29-pre3/lib/rwsem-spinlock.c
--- linux-2.4.28/lib/rwsem-spinlock.c	2004-08-07 23:26:06.000000000 +0000
+++ linux-2.4.29-pre3/lib/rwsem-spinlock.c	2004-12-22 16:05:48.000000000 +0000
@@ -32,7 +32,7 @@ void rwsemtrace(struct rw_semaphore *sem
 /*
  * initialise the semaphore
  */
-void init_rwsem(struct rw_semaphore *sem)
+void fastcall init_rwsem(struct rw_semaphore *sem)
 {
 	sem->activity = 0;
 	spin_lock_init(&sem->wait_lock);
@@ -120,7 +120,7 @@ static inline struct rw_semaphore *__rws
 /*
  * get a read lock on the semaphore
  */
-void __down_read(struct rw_semaphore *sem)
+void fastcall __down_read(struct rw_semaphore *sem)
 {
 	struct rwsem_waiter waiter;
 	struct task_struct *tsk;
@@ -166,7 +166,7 @@ void __down_read(struct rw_semaphore *se
 /*
  * trylock for reading -- returns 1 if successful, 0 if contention
  */
-int __down_read_trylock(struct rw_semaphore *sem)
+int fastcall __down_read_trylock(struct rw_semaphore *sem)
 {
 	int ret = 0;
 	rwsemtrace(sem,"Entering __down_read_trylock");
@@ -189,7 +189,7 @@ int __down_read_trylock(struct rw_semaph
  * get a write lock on the semaphore
  * - note that we increment the waiting count anyway to indicate an exclusive lock
  */
-void __down_write(struct rw_semaphore *sem)
+void fastcall __down_write(struct rw_semaphore *sem)
 {
 	struct rwsem_waiter waiter;
 	struct task_struct *tsk;
@@ -235,7 +235,7 @@ void __down_write(struct rw_semaphore *s
 /*
  * trylock for writing -- returns 1 if successful, 0 if contention
  */
-int __down_write_trylock(struct rw_semaphore *sem)
+int fastcall __down_write_trylock(struct rw_semaphore *sem)
 {
 	int ret = 0;
 	rwsemtrace(sem,"Entering __down_write_trylock");
@@ -257,7 +257,7 @@ int __down_write_trylock(struct rw_semap
 /*
  * release a read lock on the semaphore
  */
-void __up_read(struct rw_semaphore *sem)
+void fastcall __up_read(struct rw_semaphore *sem)
 {
 	rwsemtrace(sem,"Entering __up_read");
 
@@ -274,7 +274,7 @@ void __up_read(struct rw_semaphore *sem)
 /*
  * release a write lock on the semaphore
  */
-void __up_write(struct rw_semaphore *sem)
+void fastcall __up_write(struct rw_semaphore *sem)
 {
 	rwsemtrace(sem,"Entering __up_write");
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/mm/memory.c linux-2.4.29-pre3/mm/memory.c
--- linux-2.4.28/mm/memory.c	2004-12-22 16:17:24.031309376 +0000
+++ linux-2.4.29-pre3/mm/memory.c	2004-12-22 16:06:37.729562176 +0000
@@ -454,8 +454,9 @@ static inline struct page * get_page_map
 int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start,
 		int len, int write, int force, struct page **pages, struct vm_area_struct **vmas)
 {
-	int i;
+	int i, s;
 	unsigned int flags;
+	struct vm_area_struct *savevma = NULL;
 
 	/*
 	 * Require read or write permissions.
@@ -463,7 +464,7 @@ int get_user_pages(struct task_struct *t
 	 */
 	flags = write ? (VM_WRITE | VM_MAYWRITE) : (VM_READ | VM_MAYREAD);
 	flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
-	i = 0;
+	i = s = 0;
 
 	do {
 		struct vm_area_struct *	vma;
@@ -499,9 +500,13 @@ int get_user_pages(struct task_struct *t
 				/* FIXME: call the correct function,
 				 * depending on the type of the found page
 				 */
-				if (!pages[i])
-					goto bad_page;
-				page_cache_get(pages[i]);
+				if (!pages[i] || PageReserved(pages[i])) {
+					if (pages[i] != ZERO_PAGE(start)) {
+						savevma = vma;
+						goto bad_page;
+					}
+				} else
+					page_cache_get(pages[i]);
 			}
 			if (vmas)
 				vmas[i] = vma;
@@ -520,9 +525,15 @@ out:
 	 */
 bad_page:
 	spin_unlock(&mm->page_table_lock);
+	s = i;
 	while (i--)
 		page_cache_release(pages[i]);
-	i = -EFAULT;
+	/* catch bad uses of PG_reserved on !VM_IO vma's */
+	printk(KERN_ERR "get_user_pages PG_reserved page on"
+			"vma:%p flags:%lx page:%d\n", savevma,
+			savevma->vm_flags, s);
+	BUG();
+	i = -EFAULT; 
 	goto out;
 }
 
@@ -984,7 +995,8 @@ static int do_wp_page(struct mm_struct *
 		if (PageReserved(old_page))
 			++mm->rss;
 		break_cow(vma, new_page, address, page_table);
-		lru_cache_add(new_page);
+		if (vm_anon_lru)
+			lru_cache_add(new_page);
 
 		/* Free the old page.. */
 		new_page = old_page;
@@ -1215,7 +1227,8 @@ static int do_anonymous_page(struct mm_s
 		mm->rss++;
 		flush_page_to_ram(page);
 		entry = pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
-		lru_cache_add(page);
+		if (vm_anon_lru)
+			lru_cache_add(page);
 		mark_page_accessed(page);
 	}
 
@@ -1270,7 +1283,8 @@ static int do_no_page(struct mm_struct *
 		}
 		copy_user_highpage(page, new_page, address);
 		page_cache_release(new_page);
-		lru_cache_add(page);
+		if (vm_anon_lru)
+			lru_cache_add(page);
 		new_page = page;
 	}
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/mm/mmap.c linux-2.4.29-pre3/mm/mmap.c
--- linux-2.4.28/mm/mmap.c	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/mm/mmap.c	2004-12-22 16:07:03.343668240 +0000
@@ -650,7 +650,7 @@ extern unsigned long arch_get_unmapped_a
 unsigned long get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags)
 {
 	if (flags & MAP_FIXED) {
-		if (addr > TASK_SIZE - len)
+		if (addr > TASK_SIZE - len || addr >= TASK_SIZE)
 			return -ENOMEM;
 		if (addr & ~PAGE_MASK)
 			return -EINVAL;
@@ -931,7 +931,7 @@ int do_munmap(struct mm_struct *mm, unsi
 {
 	struct vm_area_struct *mpnt, *prev, **npp, *free, *extra;
 
-	if ((addr & ~PAGE_MASK) || addr > TASK_SIZE || len > TASK_SIZE-addr)
+	if ((addr & ~PAGE_MASK) || addr >= TASK_SIZE || len > TASK_SIZE-addr)
 		return -EINVAL;
 
 	if ((len = PAGE_ALIGN(len)) == 0)
@@ -1193,14 +1193,15 @@ void __insert_vm_struct(struct mm_struct
 	validate_mm(mm);
 }
 
-void insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma)
+int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma)
 {
 	struct vm_area_struct * __vma, * prev;
 	rb_node_t ** rb_link, * rb_parent;
 
 	__vma = find_vma_prepare(mm, vma->vm_start, &prev, &rb_link, &rb_parent);
 	if (__vma && __vma->vm_start < vma->vm_end)
-		BUG();
+		return -ENOMEM;
 	vma_link(mm, vma, prev, rb_link, rb_parent);
 	validate_mm(mm);
+	return 0;
 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/mm/mremap.c linux-2.4.29-pre3/mm/mremap.c
--- linux-2.4.28/mm/mremap.c	2004-04-14 13:05:41.000000000 +0000
+++ linux-2.4.29-pre3/mm/mremap.c	2004-12-22 16:06:55.851807176 +0000
@@ -196,6 +196,7 @@ static inline unsigned long move_vma(str
 			insert_vm_struct(current->mm, new_vma);
 		}
 
+		/* XXX: possible errors masked, mapping might remain */
 		do_munmap(current->mm, addr, old_len);
 
 		current->mm->total_vm += new_len >> PAGE_SHIFT;
@@ -236,6 +237,12 @@ unsigned long do_mremap(unsigned long ad
 	old_len = PAGE_ALIGN(old_len);
 	new_len = PAGE_ALIGN(new_len);
 
+	if (old_len > TASK_SIZE || addr > TASK_SIZE - old_len)
+		goto out;
+
+	if (addr >= TASK_SIZE)
+		goto out;
+
 	/* new_addr is only valid if MREMAP_FIXED is specified */
 	if (flags & MREMAP_FIXED) {
 		if (new_addr & ~PAGE_MASK)
@@ -245,6 +252,10 @@ unsigned long do_mremap(unsigned long ad
 
 		if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
 			goto out;
+
+		if (new_addr >= TASK_SIZE)
+			goto out;
+
 		/*
 		 * Allow new_len == 0 only if new_addr == addr
 		 * to preserve truncation in place (that was working
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/mm/vmscan.c linux-2.4.29-pre3/mm/vmscan.c
--- linux-2.4.28/mm/vmscan.c	2004-12-22 16:17:24.094299800 +0000
+++ linux-2.4.29-pre3/mm/vmscan.c	2004-12-22 16:05:48.000000000 +0000
@@ -65,6 +65,27 @@ int vm_lru_balance_ratio = 2;
 int vm_vfs_scan_ratio = 6;
 
 /*
+ * "vm_anon_lru" select if to immdiatly insert anon pages in the
+ * lru. Immediatly means as soon as they're allocated during the
+ * page faults.
+ *
+ * If this is set to 0, they're inserted only after the first
+ * swapout.
+ *
+ * Having anon pages immediatly inserted in the lru allows the
+ * VM to know better when it's worthwhile to start swapping
+ * anonymous ram, it will start to swap earlier and it should
+ * swap smoother and faster, but it will decrease scalability
+ * on the >16-ways of an order of magnitude. Big SMP/NUMA
+ * definitely can't take an hit on a global spinlock at
+ * every anon page allocation. So this is off by default.
+ *
+ * Low ram machines that swaps all the time want to turn
+ * this on (i.e. set to 1).
+ */
+int vm_anon_lru = 0;
+
+/*
  * The swap-out function returns 1 if it successfully
  * scanned all the pages it was asked to (`count').
  * It returns zero if it couldn't do anything,
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/net/802/p8022.c linux-2.4.29-pre3/net/802/p8022.c
--- linux-2.4.28/net/802/p8022.c	2004-08-07 23:26:06.000000000 +0000
+++ linux-2.4.29-pre3/net/802/p8022.c	2004-12-22 16:05:58.000000000 +0000
@@ -97,7 +97,14 @@ static int __init p8022_init(void)
 	return 0;
 }
 
+static void __exit p8022_exit(void)
+{
+	dev_remove_pack(&p8022_packet_type);
+	return;
+}
+
 module_init(p8022_init);
+module_exit(p8022_exit);
 
 struct datalink_proto *register_8022_client(unsigned char type, int (*rcvfunc)(struct sk_buff *, struct net_device *, struct packet_type *))
 {
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/net/802/psnap.c linux-2.4.29-pre3/net/802/psnap.c
--- linux-2.4.28/net/802/psnap.c	2004-08-07 23:26:06.000000000 +0000
+++ linux-2.4.29-pre3/net/802/psnap.c	2004-12-22 16:07:52.971123720 +0000
@@ -96,7 +96,15 @@ static int __init snap_init(void)
 		printk("SNAP - unable to register with 802.2\n");
 	return 0;
 }
+
+static void __exit snap_exit(void)
+{
+	unregister_8022_client(0xAA);
+}
+
 module_init(snap_init);
+module_exit(snap_exit);
+
 
 /*
  *	Register SNAP clients. We don't yet use this for IP.
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/net/8021q/vlan_dev.c linux-2.4.29-pre3/net/8021q/vlan_dev.c
--- linux-2.4.28/net/8021q/vlan_dev.c	2004-08-07 23:26:06.000000000 +0000
+++ linux-2.4.29-pre3/net/8021q/vlan_dev.c	2004-12-22 16:07:37.486477744 +0000
@@ -528,7 +528,7 @@ int vlan_dev_change_mtu(struct net_devic
 
 	dev->mtu = new_mtu;
 
-	return new_mtu;
+	return 0;
 }
 
 int vlan_dev_set_ingress_priority(char *dev_name, __u32 skb_prio, short vlan_prio)
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/net/bluetooth/rfcomm/tty.c linux-2.4.29-pre3/net/bluetooth/rfcomm/tty.c
--- linux-2.4.28/net/bluetooth/rfcomm/tty.c	2004-08-07 23:26:06.000000000 +0000
+++ linux-2.4.29-pre3/net/bluetooth/rfcomm/tty.c	2004-12-22 16:06:01.000000000 +0000
@@ -532,10 +532,8 @@ static void rfcomm_tty_wakeup(unsigned l
 
 	BT_DBG("dev %p tty %p", dev, tty);
 
-	if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && tty->ldisc.write_wakeup)
-                (tty->ldisc.write_wakeup)(tty);
+	tty_wakeup(tty);
 
-	wake_up_interruptible(&tty->write_wait);
 #ifdef SERIAL_HAVE_POLL_WAIT
 	wake_up_interruptible(&tty->poll_wait);
 #endif
@@ -853,8 +851,7 @@ static void rfcomm_tty_flush_buffer(stru
 
 	skb_queue_purge(&dev->dlc->tx_queue);
 
-	if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && tty->ldisc.write_wakeup)
-		tty->ldisc.write_wakeup(tty);
+	tty_wakeup(tty);
 }
 
 static void rfcomm_tty_send_xchar(struct tty_struct *tty, char ch)
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/net/core/scm.c linux-2.4.29-pre3/net/core/scm.c
--- linux-2.4.28/net/core/scm.c	2001-12-21 17:42:05.000000000 +0000
+++ linux-2.4.29-pre3/net/core/scm.c	2004-12-22 16:06:26.568258952 +0000
@@ -124,9 +124,7 @@ int __scm_send(struct socket *sock, stru
 		   for too short ancillary data object at all! Oops.
 		   OK, let's add it...
 		 */
-		if (cmsg->cmsg_len < sizeof(struct cmsghdr) ||
-		    (unsigned long)(((char*)cmsg - (char*)msg->msg_control)
-				    + cmsg->cmsg_len) > msg->msg_controllen)
+		if (!CMSG_OK(msg, cmsg))
 			goto error;
 
 		if (cmsg->cmsg_level != SOL_SOCKET)
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/net/decnet/dn_neigh.c linux-2.4.29-pre3/net/decnet/dn_neigh.c
--- linux-2.4.28/net/decnet/dn_neigh.c	2004-12-22 16:17:24.249276240 +0000
+++ linux-2.4.29-pre3/net/decnet/dn_neigh.c	2004-12-22 16:07:11.192475040 +0000
@@ -26,6 +26,7 @@
 
 #include <linux/config.h>
 #include <linux/net.h>
+#include <linux/module.h>
 #include <linux/socket.h>
 #include <linux/if_arp.h>
 #include <linux/if_ether.h>
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/net/ipv4/af_inet.c linux-2.4.29-pre3/net/ipv4/af_inet.c
--- linux-2.4.28/net/ipv4/af_inet.c	2004-08-07 23:26:06.000000000 +0000
+++ linux-2.4.29-pre3/net/ipv4/af_inet.c	2004-12-22 16:05:48.000000000 +0000
@@ -972,6 +972,27 @@ struct proto_ops inet_dgram_ops = {
 	socketpair:	sock_no_socketpair,
 	accept:		sock_no_accept,
 	getname:	inet_getname, 
+	poll:		udp_poll,
+	ioctl:		inet_ioctl,
+	listen:		sock_no_listen,
+	shutdown:	inet_shutdown,
+	setsockopt:	inet_setsockopt,
+	getsockopt:	inet_getsockopt,
+	sendmsg:	inet_sendmsg,
+	recvmsg:	inet_recvmsg,
+	mmap:		sock_no_mmap,
+	sendpage:	sock_no_sendpage,
+};
+
+struct proto_ops inet_sockraw_ops = {
+	family:		PF_INET,
+
+	release:	inet_release,
+	bind:		inet_bind,
+	connect:	inet_dgram_connect,
+	socketpair:	sock_no_socketpair,
+	accept:		sock_no_accept,
+	getname:	inet_getname, 
 	poll:		datagram_poll,
 	ioctl:		inet_ioctl,
 	listen:		sock_no_listen,
@@ -1023,7 +1044,7 @@ static struct inet_protosw inetsw_array[
                type:        SOCK_RAW,
                protocol:    IPPROTO_IP,	/* wild card */
                prot:        &raw_prot,
-               ops:         &inet_dgram_ops,
+               ops:         &inet_sockraw_ops,
                capability:  CAP_NET_RAW,
                no_check:    UDP_CSUM_DEFAULT,
                flags:       INET_PROTOSW_REUSE,
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/net/ipv4/igmp.c linux-2.4.29-pre3/net/ipv4/igmp.c
--- linux-2.4.28/net/ipv4/igmp.c	2004-08-07 23:26:06.000000000 +0000
+++ linux-2.4.29-pre3/net/ipv4/igmp.c	2004-12-22 16:07:45.266295032 +0000
@@ -1757,12 +1757,12 @@ int ip_mc_source(int add, int omode, str
 			goto done;
 		rv = !0;
 		for (i=0; i<psl->sl_count; i++) {
-			rv = memcmp(&psl->sl_addr, &mreqs->imr_multiaddr,
+			rv = memcmp(&psl->sl_addr[i], &mreqs->imr_sourceaddr,
 				sizeof(__u32));
-			if (rv >= 0)
+			if (rv == 0)
 				break;
 		}
-		if (!rv)	/* source not found */
+		if (rv)		/* source not found */
 			goto done;
 
 		/* update the interface filter */
@@ -1804,9 +1804,9 @@ int ip_mc_source(int add, int omode, str
 	}
 	rv = 1;	/* > 0 for insert logic below if sl_count is 0 */
 	for (i=0; i<psl->sl_count; i++) {
-		rv = memcmp(&psl->sl_addr, &mreqs->imr_multiaddr,
+		rv = memcmp(&psl->sl_addr[i], &mreqs->imr_sourceaddr,
 			sizeof(__u32));
-		if (rv >= 0)
+		if (rv == 0)
 			break;
 	}
 	if (rv == 0)		/* address already there is an error */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/net/ipv4/ip_options.c linux-2.4.29-pre3/net/ipv4/ip_options.c
--- linux-2.4.28/net/ipv4/ip_options.c	2002-11-28 23:53:15.000000000 +0000
+++ linux-2.4.29-pre3/net/ipv4/ip_options.c	2004-12-22 16:07:14.254009616 +0000
@@ -514,6 +514,8 @@ int ip_options_get(struct ip_options **o
 		kfree(opt);
 		return -EINVAL;
 	}
+	if (*optp)
+		kfree(*optp);
 	*optp = opt;
 	return 0;
 }
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/net/ipv4/ip_sockglue.c linux-2.4.29-pre3/net/ipv4/ip_sockglue.c
--- linux-2.4.28/net/ipv4/ip_sockglue.c	2004-08-07 23:26:06.000000000 +0000
+++ linux-2.4.29-pre3/net/ipv4/ip_sockglue.c	2004-12-22 16:06:15.408955424 +0000
@@ -143,11 +143,8 @@ int ip_cmsg_send(struct msghdr *msg, str
 	struct cmsghdr *cmsg;
 
 	for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
-		if (cmsg->cmsg_len < sizeof(struct cmsghdr) ||
-		    (unsigned long)(((char*)cmsg - (char*)msg->msg_control)
-				    + cmsg->cmsg_len) > msg->msg_controllen) {
+		if (!CMSG_OK(msg, cmsg))
 			return -EINVAL;
-		}
 		if (cmsg->cmsg_level != SOL_IP)
 			continue;
 		switch (cmsg->cmsg_type) {
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/net/ipv4/ipvs/ip_vs_conn.c linux-2.4.29-pre3/net/ipv4/ipvs/ip_vs_conn.c
--- linux-2.4.28/net/ipv4/ipvs/ip_vs_conn.c	2004-04-14 13:05:41.000000000 +0000
+++ linux-2.4.29-pre3/net/ipv4/ipvs/ip_vs_conn.c	2004-12-22 16:07:14.681944560 +0000
@@ -1131,7 +1131,9 @@ int ip_vs_check_template(struct ip_vs_co
 	 * Checking the dest server status.
 	 */
 	if ((dest == NULL) ||
-	    !(dest->flags & IP_VS_DEST_F_AVAILABLE)) {
+	    !(dest->flags & IP_VS_DEST_F_AVAILABLE) || 
+	    (sysctl_ip_vs_expire_quiescent_template && 
+	     (atomic_read(&dest->weight) == 0))) {
 		IP_VS_DBG(9, "check_template: dest not available for "
 			  "protocol %s s:%u.%u.%u.%u:%d v:%u.%u.%u.%u:%d "
 			  "-> d:%u.%u.%u.%u:%d\n",
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/net/ipv4/ipvs/ip_vs_ctl.c linux-2.4.29-pre3/net/ipv4/ipvs/ip_vs_ctl.c
--- linux-2.4.28/net/ipv4/ipvs/ip_vs_ctl.c	2004-04-14 13:05:41.000000000 +0000
+++ linux-2.4.29-pre3/net/ipv4/ipvs/ip_vs_ctl.c	2004-12-22 16:06:24.592559304 +0000
@@ -74,6 +74,7 @@ static int sysctl_ip_vs_amemthresh = 204
 static int sysctl_ip_vs_am_droprate = 10;
 int sysctl_ip_vs_cache_bypass = 0;
 int sysctl_ip_vs_expire_nodest_conn = 0;
+int sysctl_ip_vs_expire_quiescent_template = 0;
 int sysctl_ip_vs_sync_threshold = 3;
 int sysctl_ip_vs_nat_icmp_send = 0;
 
@@ -1440,6 +1441,9 @@ static struct ip_vs_sysctl_table ipv4_vs
 	 {NET_IPV4_VS_NAT_ICMP_SEND, "nat_icmp_send",
 	  &sysctl_ip_vs_nat_icmp_send, sizeof(int), 0644, NULL,
 	  &proc_dointvec},
+	 {NET_IPV4_VS_EXPIRE_QUIESCENT_TEMPLATE, "expire_quiescent_template",
+	  &sysctl_ip_vs_expire_quiescent_template, sizeof(int), 0644, NULL,
+	  &proc_dointvec},
 	 {0}},
 	{{NET_IPV4_VS, "vs", NULL, 0, 0555, ipv4_vs_table.vs_vars},
 	 {0}},
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/net/ipv4/tcp_input.c linux-2.4.29-pre3/net/ipv4/tcp_input.c
--- linux-2.4.28/net/ipv4/tcp_input.c	2004-12-22 16:17:24.499238240 +0000
+++ linux-2.4.29-pre3/net/ipv4/tcp_input.c	2004-12-22 16:05:57.000000000 +0000
@@ -474,6 +474,8 @@ void tcp_rcv_space_adjust(struct sock *s
 		tp->rcvq_space.space = space;
 
 		if (sysctl_tcp_moderate_rcvbuf) {
+			int new_clamp = space;
+
 			/* Receive space grows, normalize in order to
 			 * take into account packet headers and sk_buff
 			 * structure overhead.
@@ -483,10 +485,16 @@ void tcp_rcv_space_adjust(struct sock *s
 				space = 1;
 			rcvmem = (tp->advmss + MAX_TCP_HEADER +
 				  16 + sizeof(struct sk_buff));
+			while (tcp_win_from_space(rcvmem) < tp->advmss)
+				rcvmem += 128;
 			space *= rcvmem;
 			space = min(space, sysctl_tcp_rmem[2]);
-			if (space > sk->rcvbuf)
+			if (space > sk->rcvbuf) {
 				sk->rcvbuf = space;
+
+				/* Make the window clamp follow along.  */
+				tp->window_clamp = new_clamp;
+			}
 		}
 	}
 	
@@ -2900,8 +2908,8 @@ void tcp_parse_options(struct sk_buff *s
 							tp->snd_wscale = *(__u8 *)ptr;
 							if(tp->snd_wscale > 14) {
 								if(net_ratelimit())
-									printk("tcp_parse_options: Illegal window "
-									       "scaling value %d >14 received.",
+									printk(KERN_INFO "tcp_parse_options: Illegal window "
+									       "scaling value %d >14 received.\n",
 									       tp->snd_wscale);
 								tp->snd_wscale = 14;
 							}
@@ -3137,7 +3145,7 @@ static void tcp_fin(struct sk_buff *skb,
 			/* Only TCP_LISTEN and TCP_CLOSE are left, in these
 			 * cases we should never reach this piece of code.
 			 */
-			printk("tcp_fin: Impossible, sk->state=%d\n", sk->state);
+			printk(KERN_ERR "tcp_fin: Impossible, sk->state=%d\n", sk->state);
 			break;
 	};
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/net/ipv4/udp.c linux-2.4.29-pre3/net/ipv4/udp.c
--- linux-2.4.28/net/ipv4/udp.c	2004-08-07 23:26:07.000000000 +0000
+++ linux-2.4.29-pre3/net/ipv4/udp.c	2004-12-22 16:05:52.000000000 +0000
@@ -371,7 +371,6 @@ out:
 	sock_put(sk);
 }
 
-
 static unsigned short udp_check(struct udphdr *uh, int len, unsigned long saddr, unsigned long daddr, unsigned long base)
 {
 	return(csum_tcpudp_magic(saddr, daddr, len, IPPROTO_UDP, base));
@@ -636,6 +635,55 @@ static __inline__ int udp_checksum_compl
 		__udp_checksum_complete(skb);
 }
 
+
+/**
+ * 	udp_poll - wait for a UDP event.
+ *	@file - file struct
+ *	@sock - socket
+ *	@wait - poll table
+ *
+ *	This is same as datagram poll, except for the special case of 
+ *	blocking sockets. If application is using a blocking fd
+ *	and a packet with checksum error is in the queue;
+ *	then it could get return from select indicating data available
+ *	but then block when reading it. Add special case code
+ *	to work around these arguably broken applications.
+ */
+unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait)
+{
+	unsigned int mask = datagram_poll(file, sock, wait);
+	struct sock *sk = sock->sk;
+	
+	/* Check for false positives due to checksum errors */
+	if ( (mask & POLLRDNORM) &&
+	     !(file->f_flags & O_NONBLOCK) &&
+	     !(sk->shutdown & RCV_SHUTDOWN)){
+		struct sk_buff_head *rcvq = &sk->receive_queue;
+		struct sk_buff *skb;
+
+		spin_lock_irq(&rcvq->lock);
+		while ((skb = skb_peek(rcvq)) != NULL) {
+			if (udp_checksum_complete(skb)) {
+				UDP_INC_STATS_BH(UdpInErrors);
+				IP_INC_STATS_BH(IpInDiscards);
+				__skb_unlink(skb, rcvq);
+				kfree_skb(skb);
+			} else {
+				skb->ip_summed = CHECKSUM_UNNECESSARY;
+				break;
+			}
+		}
+		spin_unlock_irq(&rcvq->lock);
+
+		/* nothing to see, move along */
+		if (skb == NULL)
+			mask &= ~(POLLIN | POLLRDNORM);
+	}
+
+	return mask;
+	
+}
+
 /*
  * 	This should be easy, if there is something there we
  * 	return it, otherwise we block.
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/net/ipv6/af_inet6.c linux-2.4.29-pre3/net/ipv6/af_inet6.c
--- linux-2.4.28/net/ipv6/af_inet6.c	2004-12-22 16:17:24.576226536 +0000
+++ linux-2.4.29-pre3/net/ipv6/af_inet6.c	2004-12-22 16:06:56.676681776 +0000
@@ -497,6 +497,27 @@ struct proto_ops inet6_dgram_ops = {
 	socketpair:	sock_no_socketpair,		/* a do nothing	*/
 	accept:		sock_no_accept,			/* a do nothing	*/
 	getname:	inet6_getname, 
+	poll:		udp_poll,			/* ok		*/
+	ioctl:		inet6_ioctl,			/* must change  */
+	listen:		sock_no_listen,			/* ok		*/
+	shutdown:	inet_shutdown,			/* ok		*/
+	setsockopt:	inet_setsockopt,		/* ok		*/
+	getsockopt:	inet_getsockopt,		/* ok		*/
+	sendmsg:	inet_sendmsg,			/* ok		*/
+	recvmsg:	inet_recvmsg,			/* ok		*/
+	mmap:		sock_no_mmap,
+	sendpage:	sock_no_sendpage,
+};
+
+struct proto_ops inet6_sockraw_ops = {
+	family:		PF_INET6,
+
+	release:	inet6_release,
+	bind:		inet6_bind,
+	connect:	inet_dgram_connect,		/* ok		*/
+	socketpair:	sock_no_socketpair,		/* a do nothing	*/
+	accept:		sock_no_accept,			/* a do nothing	*/
+	getname:	inet6_getname, 
 	poll:		datagram_poll,			/* ok		*/
 	ioctl:		inet6_ioctl,			/* must change  */
 	listen:		sock_no_listen,			/* ok		*/
@@ -532,7 +553,7 @@ static struct inet_protosw rawv6_protosw
 	type:        SOCK_RAW,
 	protocol:    IPPROTO_IP,	/* wild card */
 	prot:        &rawv6_prot,
-	ops:         &inet6_dgram_ops,
+	ops:         &inet6_sockraw_ops,
 	capability:  CAP_NET_RAW,
 	no_check:    UDP_CSUM_DEFAULT,
 	flags:       INET_PROTOSW_REUSE,
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/net/ipv6/datagram.c linux-2.4.29-pre3/net/ipv6/datagram.c
--- linux-2.4.28/net/ipv6/datagram.c	2004-12-22 16:17:24.578226232 +0000
+++ linux-2.4.29-pre3/net/ipv6/datagram.c	2004-12-22 16:05:42.000000000 +0000
@@ -260,9 +260,7 @@ int datagram_send_ctl(struct msghdr *msg
 
 	for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
 
-		if (cmsg->cmsg_len < sizeof(struct cmsghdr) ||
-		    (unsigned long)(((char*)cmsg - (char*)msg->msg_control)
-				    + cmsg->cmsg_len) > msg->msg_controllen) {
+		if (!CMSG_OK(msg, cmsg)) {
 			err = -EINVAL;
 			goto exit_f;
 		}
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/net/ipv6/mcast.c linux-2.4.29-pre3/net/ipv6/mcast.c
--- linux-2.4.28/net/ipv6/mcast.c	2004-12-22 16:17:24.626218936 +0000
+++ linux-2.4.29-pre3/net/ipv6/mcast.c	2004-12-22 16:07:32.733200352 +0000
@@ -386,12 +386,12 @@ int ip6_mc_source(int add, int omode, st
 			goto done;
 		rv = !0;
 		for (i=0; i<psl->sl_count; i++) {
-			rv = memcmp(&psl->sl_addr, group,
+			rv = memcmp(&psl->sl_addr[i], source,
 				sizeof(struct in6_addr));
-			if (rv >= 0)
+			if (rv == 0)
 				break;
 		}
-		if (!rv)	/* source not found */
+		if (rv)		/* source not found */
 			goto done;
 
 		/* update the interface filter */
@@ -432,8 +432,8 @@ int ip6_mc_source(int add, int omode, st
 	}
 	rv = 1;	/* > 0 for insert logic below if sl_count is 0 */
 	for (i=0; i<psl->sl_count; i++) {
-		rv = memcmp(&psl->sl_addr, group, sizeof(struct in6_addr));
-		if (rv >= 0)
+		rv = memcmp(&psl->sl_addr[i], source, sizeof(struct in6_addr));
+		if (rv == 0)
 			break;
 	}
 	if (rv == 0)		/* address already there is an error */
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/net/irda/ircomm/ircomm_tty.c linux-2.4.29-pre3/net/irda/ircomm/ircomm_tty.c
--- linux-2.4.28/net/irda/ircomm/ircomm_tty.c	2003-08-25 11:44:44.000000000 +0000
+++ linux-2.4.29-pre3/net/irda/ircomm/ircomm_tty.c	2004-12-22 16:06:18.844433152 +0000
@@ -566,8 +566,7 @@ static void ircomm_tty_close(struct tty_
 
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
+	tty_ldisc_flush(tty);
 
 	tty->closing = 0;
 	self->tty = 0;
@@ -662,12 +661,7 @@ static void ircomm_tty_do_softint(void *
 		ircomm_tty_do_event(self, IRCOMM_TTY_DATA_REQUEST, skb, NULL);
 		
 	/* Check if user (still) wants to be waken up */
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && 
-	    tty->ldisc.write_wakeup)
-	{
-		(tty->ldisc.write_wakeup)(tty);
-	}
-	wake_up_interruptible(&tty->write_wait);
+	tty_wakeup(tty);
 }
 
 /*
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/net/netlink/af_netlink.c linux-2.4.29-pre3/net/netlink/af_netlink.c
--- linux-2.4.28/net/netlink/af_netlink.c	2004-02-18 13:36:32.000000000 +0000
+++ linux-2.4.29-pre3/net/netlink/af_netlink.c	2004-12-22 16:06:46.112287808 +0000
@@ -40,6 +40,11 @@
 #include <linux/proc_fs.h>
 #include <linux/smp_lock.h>
 #include <linux/notifier.h>
+#include <linux/jhash.h>
+#include <linux/random.h>
+#include <linux/bitops.h>
+#include <linux/mm.h>
+#include <linux/types.h>
 #include <net/sock.h>
 #include <net/scm.h>
 
@@ -52,9 +57,9 @@
 struct netlink_opt
 {
 	u32			pid;
-	unsigned		groups;
+	unsigned int		groups;
 	u32			dst_pid;
-	unsigned		dst_groups;
+	unsigned int		dst_groups;
 	unsigned long		state;
 	int			(*handler)(int unit, struct sk_buff *skb);
 	wait_queue_head_t	wait;
@@ -63,9 +68,30 @@ struct netlink_opt
 	void			(*data_ready)(struct sock *sk, int bytes);
 };
 
-static struct sock *nl_table[MAX_LINKS];
+struct nl_pid_hash {
+	struct sock **table;
+	unsigned long rehash_time;
+
+	unsigned int mask;
+	unsigned int shift;
+
+	unsigned int entries;
+	unsigned int max_shift;
+
+	u32 rnd;
+};
+
+struct netlink_table {
+	struct nl_pid_hash hash;
+	struct sock *mc_list;
+};
+
+#define nlk_sk(__sk) ((__sk)->protinfo.af_netlink)
+
+static struct netlink_table *nl_table;
+
 static DECLARE_WAIT_QUEUE_HEAD(nl_table_wait);
-static unsigned nl_nonroot[MAX_LINKS];
+static unsigned int nl_nonroot[MAX_LINKS];
 
 #ifdef NL_EMULATE_DEV
 static struct socket *netlink_kernel[MAX_LINKS];
@@ -81,6 +107,11 @@ static atomic_t nl_table_users = ATOMIC_
 
 static struct notifier_block *netlink_chain;
 
+static struct sock **nl_pid_hashfn(struct nl_pid_hash *hash, u32 pid)
+{
+	return &hash->table[jhash_1word(pid, hash->rnd) & hash->mask];
+}
+
 static void netlink_sock_destruct(struct sock *sk)
 {
 	skb_queue_purge(&sk->receive_queue);
@@ -154,10 +185,11 @@ netlink_unlock_table(void)
 
 static __inline__ struct sock *netlink_lookup(int protocol, u32 pid)
 {
+	struct nl_pid_hash *hash = &nl_table[protocol].hash;
 	struct sock *sk;
 
 	read_lock(&nl_table_lock);
-	for (sk=nl_table[protocol]; sk; sk=sk->next) {
+	for (sk = *nl_pid_hashfn(hash, pid); sk; sk = sk->next) {
 		if (sk->protinfo.af_netlink->pid == pid) {
 			sock_hold(sk);
 			read_unlock(&nl_table_lock);
@@ -169,28 +201,123 @@ static __inline__ struct sock *netlink_l
 	return NULL;
 }
 
+static inline struct sock **nl_pid_hash_alloc(size_t size)
+{
+	if (size <= PAGE_SIZE)
+		return kmalloc(size, GFP_ATOMIC);
+	else
+		return (struct sock **)
+			__get_free_pages(GFP_ATOMIC, get_order(size));
+}
+
+static inline void nl_pid_hash_free(struct sock **table, size_t size)
+{
+	if (size <= PAGE_SIZE)
+		kfree(table);
+	else
+		free_pages((unsigned long)table, get_order(size));
+}
+
+static int nl_pid_hash_rehash(struct nl_pid_hash *hash, int grow)
+{
+	unsigned int omask, mask, shift;
+	size_t osize, size;
+	struct sock **otable, **table;
+	int i;
+
+	omask = mask = hash->mask;
+	osize = size = (mask + 1) * sizeof(*table);
+	shift = hash->shift;
+
+	if (grow) {
+		if (++shift > hash->max_shift)
+			return 0;
+		mask = mask * 2 + 1;
+		size *= 2;
+	}
+
+	table = nl_pid_hash_alloc(size);
+	if (!table)
+		return 0;
+
+	memset(table, 0, size);
+	otable = hash->table;
+	hash->table = table;
+	hash->mask = mask;
+	hash->shift = shift;
+	get_random_bytes(&hash->rnd, sizeof(hash->rnd));
+
+	for (i = 0; i <= omask; i++) {
+		struct sock *sk;
+		struct sock *tmp, **head;
+
+		for (sk = otable[i]; sk; sk = tmp) {
+			tmp = sk->next;
+			head = nl_pid_hashfn(hash, nlk_sk(sk)->pid);
+			sk->next = *head;
+			*head = sk;
+		}
+	}
+
+	nl_pid_hash_free(otable, osize);
+	hash->rehash_time = jiffies + 10 * 60 * HZ;
+	return 1;
+}
+
+static inline int nl_pid_hash_dilute(struct nl_pid_hash *hash, int len)
+{
+	int avg = hash->entries >> hash->shift;
+
+	if (unlikely(avg > 1) && nl_pid_hash_rehash(hash, 1))
+		return 1;
+
+	if (unlikely(len > avg) && time_after(jiffies, hash->rehash_time)) {
+		nl_pid_hash_rehash(hash, 0);
+		return 1;
+	}
+
+	return 0;
+}
+
 extern struct proto_ops netlink_ops;
 
 static int netlink_insert(struct sock *sk, u32 pid)
 {
+	struct nl_pid_hash *hash = &nl_table[sk->protocol].hash;
+	struct sock **head;
 	int err = -EADDRINUSE;
 	struct sock *osk;
+	int len;
 
 	netlink_table_grab();
-	for (osk=nl_table[sk->protocol]; osk; osk=osk->next) {
+	head = nl_pid_hashfn(hash, pid);
+	len = 0;
+	for (osk = *head; osk; osk = osk->next) {
 		if (osk->protinfo.af_netlink->pid == pid)
 			break;
+		len++;
 	}
-	if (osk == NULL) {
-		err = -EBUSY;
-		if (sk->protinfo.af_netlink->pid == 0) {
-			sk->protinfo.af_netlink->pid = pid;
-			sk->next = nl_table[sk->protocol];
-			nl_table[sk->protocol] = sk;
-			sock_hold(sk);
-			err = 0;
-		}
-	}
+	if (osk)
+		goto err;
+
+	err = -EBUSY;
+	if (nlk_sk(sk)->pid)
+		goto err;
+
+	err = -ENOMEM;
+	if (BITS_PER_LONG > 32 && unlikely(hash->entries >= UINT_MAX))
+		goto err;
+
+	if (len && nl_pid_hash_dilute(hash, len))
+		head = nl_pid_hashfn(hash, pid);
+	hash->entries++;
+	nlk_sk(sk)->pid = pid;
+	sk->next = *head;
+	*head = sk;
+	sock_hold(sk);
+	err = 0;
+
+err:
 	netlink_table_ungrab();
 	return err;
 }
@@ -198,15 +325,27 @@ static int netlink_insert(struct sock *s
 static void netlink_remove(struct sock *sk)
 {
 	struct sock **skp;
+	struct netlink_table *table = &nl_table[sk->protocol];
+	struct nl_pid_hash *hash = &table->hash;
 
 	netlink_table_grab();
-	for (skp = &nl_table[sk->protocol]; *skp; skp = &((*skp)->next)) {
+	hash->entries--;
+	for (skp = hash->table; *skp; skp = &((*skp)->next)) {
 		if (*skp == sk) {
 			*skp = sk->next;
 			__sock_put(sk);
 			break;
 		}
 	}
+	if (!nlk_sk(sk)->groups)
+		goto out;
+	for (skp = &table->mc_list; *skp; skp = &((*skp)->next)) {
+		if (*skp == sk) {
+			*skp = sk->next;
+			break;
+		}
+	}
+out:
 	netlink_table_ungrab();
 }
 
@@ -286,18 +425,21 @@ static int netlink_release(struct socket
 static int netlink_autobind(struct socket *sock)
 {
 	struct sock *sk = sock->sk;
+	struct nl_pid_hash *hash = &nl_table[sk->protocol].hash;
 	struct sock *osk;
 	s32 pid = current->pid;
 	int err;
+	static s32 rover = -4097;
 
 retry:
+	cond_resched();
 	netlink_table_grab();
-	for (osk=nl_table[sk->protocol]; osk; osk=osk->next) {
+	for (osk = *nl_pid_hashfn(hash, pid); osk; osk = osk->next) {
 		if (osk->protinfo.af_netlink->pid == pid) {
 			/* Bind collision, search negative pid values. */
-			if (pid > 0)
-				pid = -4096;
-			pid--;
+			pid = rover--;
+			if (rover > -4097)
+				rover = -4097;
 			netlink_table_ungrab();
 			goto retry;
 		}
@@ -311,7 +453,7 @@ retry:
 	return 0;
 }
 
-static inline int netlink_capable(struct socket *sock, unsigned flag) 
+static inline int netlink_capable(struct socket *sock, unsigned int flag) 
 { 
 	return (nl_nonroot[sock->sk->protocol] & flag) || capable(CAP_NET_ADMIN);
 } 
@@ -319,7 +461,9 @@ static inline int netlink_capable(struct
 static int netlink_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
 {
 	struct sock *sk = sock->sk;
+	struct sock **skp;
 	int err;
+	struct netlink_opt *nlk = nlk_sk(sk);
 	struct sockaddr_nl *nladdr=(struct sockaddr_nl *)addr;
 	
 	if (nladdr->nl_family != AF_NETLINK)
@@ -332,21 +476,34 @@ static int netlink_bind(struct socket *s
 	if (sk->protinfo.af_netlink->pid) {
 		if (nladdr->nl_pid != sk->protinfo.af_netlink->pid)
 			return -EINVAL;
-		sk->protinfo.af_netlink->groups = nladdr->nl_groups;
-		return 0;
+	} else {
+		err = nladdr->nl_pid ?
+			netlink_insert(sk, nladdr->nl_pid) :
+			netlink_autobind(sock);
+		if (err)
+			return err;
 	}
 
-	if (nladdr->nl_pid == 0) {
-		err = netlink_autobind(sock);
-		if (err == 0)
-			sk->protinfo.af_netlink->groups = nladdr->nl_groups;
-		return err;
+	if (!nladdr->nl_groups && !nlk->groups)
+		return 0;
+
+	netlink_table_grab();
+	skp = &nl_table[sk->protocol].mc_list;
+	if (nlk->groups && !nladdr->nl_groups) {
+		for (; *skp; skp = &((*skp)->bind_next)) {
+			if (*skp == sk) {
+				*skp = sk->bind_next;
+				break;
+			}
+		}
+	} else if (!nlk->groups && nladdr->nl_groups) {
+		sk->bind_next = *skp;
+		*skp = sk;
 	}
+	nlk->groups = nladdr->nl_groups;
+	netlink_table_ungrab();
 
-	err = netlink_insert(sk, nladdr->nl_pid);
-	if (err == 0)
-		sk->protinfo.af_netlink->groups = nladdr->nl_groups;
-	return err;
+	return 0;
 }
 
 static int netlink_connect(struct socket *sock, struct sockaddr *addr,
@@ -496,75 +653,120 @@ static __inline__ int netlink_broadcast_
 	return -1;
 }
 
+struct netlink_broadcast_data {
+	struct sock *exclude_sk;
+	u32 pid;
+	u32 group;
+	int failure;
+	int allocation;
+	struct sk_buff *skb, *skb2;
+};
+
+static inline int do_one_broadcast(struct sock *sk,
+				   struct netlink_broadcast_data *p)
+{
+	struct netlink_opt *nlk = nlk_sk(sk);
+	int val;
+
+	if (p->exclude_sk == sk)
+		goto out;
+
+	if (nlk->pid == p->pid || !(nlk->groups & p->group))
+		goto out;
+
+	if (p->failure) {
+		netlink_overrun(sk);
+		goto out;
+	}
+
+	sock_hold(sk);
+	if (p->skb2 == NULL) {
+		if (atomic_read(&p->skb->users) != 1) {
+			p->skb2 = skb_clone(p->skb, p->allocation);
+		} else {
+			p->skb2 = p->skb;
+			atomic_inc(&p->skb->users);
+		}
+	}
+	if (p->skb2 == NULL) {
+		netlink_overrun(sk);
+		/* Clone failed. Notify ALL listeners. */
+		p->failure = 1;
+	} else if ((val = netlink_broadcast_deliver(sk, p->skb2)) < 0) {
+		netlink_overrun(sk);
+	} else
+		p->skb2 = NULL;
+	sock_put(sk);
+
+out:
+	return 0;
+}
+
 void netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 pid,
 		       u32 group, int allocation)
 {
+	struct netlink_broadcast_data info;
 	struct sock *sk;
-	struct sk_buff *skb2 = NULL;
-	int protocol = ssk->protocol;
-	int failure = 0;
+
+	info.exclude_sk = ssk;
+	info.pid = pid;
+	info.group = group;
+	info.failure = 0;
+	info.allocation = allocation;
+	info.skb = skb;
+	info.skb2 = NULL;
 
 	/* While we sleep in clone, do not allow to change socket list */
 
 	netlink_lock_table();
 
-	for (sk = nl_table[protocol]; sk; sk = sk->next) {
-		if (ssk == sk)
-			continue;
-
-		if (sk->protinfo.af_netlink->pid == pid ||
-		    !(sk->protinfo.af_netlink->groups&group))
-			continue;
-
-		if (failure) {
-			netlink_overrun(sk);
-			continue;
-		}
-
-		sock_hold(sk);
-		if (skb2 == NULL) {
-			if (atomic_read(&skb->users) != 1) {
-				skb2 = skb_clone(skb, allocation);
-			} else {
-				skb2 = skb;
-				atomic_inc(&skb->users);
-			}
-		}
-		if (skb2 == NULL) {
-			netlink_overrun(sk);
-			/* Clone failed. Notify ALL listeners. */
-			failure = 1;
-		} else if (netlink_broadcast_deliver(sk, skb2)) {
-			netlink_overrun(sk);
-		} else
-			skb2 = NULL;
-		sock_put(sk);
-	}
+	for (sk = nl_table[ssk->protocol].mc_list; sk; sk = sk->bind_next)
+		do_one_broadcast(sk, &info);
 
 	netlink_unlock_table();
 
-	if (skb2)
-		kfree_skb(skb2);
+	if (info.skb2)
+		kfree_skb(info.skb2);
 	kfree_skb(skb);
 }
 
+struct netlink_set_err_data {
+	struct sock *exclude_sk;
+	u32 pid;
+	u32 group;
+	int code;
+};
+
+static inline int do_one_set_err(struct sock *sk,
+				 struct netlink_set_err_data *p)
+{
+	struct netlink_opt *nlk = nlk_sk(sk);
+
+	if (sk == p->exclude_sk)
+		goto out;
+
+	if (nlk->pid == p->pid || !(nlk->groups & p->group))
+		goto out;
+
+	sk->err = p->code;
+	sk->error_report(sk);
+out:
+	return 0;
+}
+
 void netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code)
 {
+	struct netlink_set_err_data info;
 	struct sock *sk;
-	int protocol = ssk->protocol;
 
-	read_lock(&nl_table_lock);
-	for (sk = nl_table[protocol]; sk; sk = sk->next) {
-		if (ssk == sk)
-			continue;
-
-		if (sk->protinfo.af_netlink->pid == pid ||
-		    !(sk->protinfo.af_netlink->groups&group))
-			continue;
+	info.exclude_sk = ssk;
+	info.pid = pid;
+	info.group = group;
+	info.code = code;
 
-		sk->err = code;
-		sk->error_report(sk);
-	}
+	read_lock(&nl_table_lock);
+	for (sk = nl_table[ssk->protocol].mc_list; sk; sk = sk->bind_next)
+		do_one_set_err(sk, &info);
 	read_unlock(&nl_table_lock);
 }
 
@@ -713,6 +915,9 @@ netlink_kernel_create(int unit, void (*i
 	struct socket *sock;
 	struct sock *sk;
 
+	if (!nl_table)
+		return NULL;
+
 	if (unit<0 || unit>=MAX_LINKS)
 		return NULL;
 
@@ -734,9 +939,9 @@ netlink_kernel_create(int unit, void (*i
 	return sk;
 }
 
-void netlink_set_nonroot(int protocol, unsigned flags)
+void netlink_set_nonroot(int protocol, unsigned int flags)
 { 
-	if ((unsigned)protocol < MAX_LINKS) 
+	if ((unsigned int)protocol < MAX_LINKS) 
 		nl_nonroot[protocol] = flags;
 } 
 
@@ -926,42 +1131,51 @@ int netlink_post(int unit, struct sk_buf
 
 
 #ifdef CONFIG_PROC_FS
+struct nl_seq_iter {
+	int link;
+	int hash_idx;
+};
+
 static int netlink_read_proc(char *buffer, char **start, off_t offset,
 			     int length, int *eof, void *data)
 {
 	off_t pos=0;
 	off_t begin=0;
 	int len=0;
-	int i;
+	int i, j;
 	struct sock *s;
 	
 	len+= sprintf(buffer,"sk       Eth Pid    Groups   "
 		      "Rmem     Wmem     Dump     Locks\n");
 	
 	for (i=0; i<MAX_LINKS; i++) {
+		struct nl_pid_hash *hash = &nl_table[i].hash;
+
 		read_lock(&nl_table_lock);
-		for (s = nl_table[i]; s; s = s->next) {
-			len+=sprintf(buffer+len,"%p %-3d %-6d %08x %-8d %-8d %p %d",
-				     s,
-				     s->protocol,
-				     s->protinfo.af_netlink->pid,
-				     s->protinfo.af_netlink->groups,
-				     atomic_read(&s->rmem_alloc),
-				     atomic_read(&s->wmem_alloc),
-				     s->protinfo.af_netlink->cb,
-				     atomic_read(&s->refcnt)
-				     );
+		for (j = 0; j <= hash->mask; j++) {
+			for (s = hash->table[j]; s; s = s->next) {
+				len += sprintf(buffer + len,
+					       "%p %-3d %-6d %08x %-8d %-8d %p %d",
+					       s,
+					       s->protocol,
+					       s->protinfo.af_netlink->pid,
+					       s->protinfo.af_netlink->groups,
+					       atomic_read(&s->rmem_alloc),
+					       atomic_read(&s->wmem_alloc),
+					       s->protinfo.af_netlink->cb,
+					       atomic_read(&s->refcnt));
 
-			buffer[len++]='\n';
+				buffer[len++]='\n';
 		
-			pos=begin+len;
-			if(pos<offset) {
-				len=0;
-				begin=pos;
-			}
-			if(pos>offset+length) {
-				read_unlock(&nl_table_lock);
-				goto done;
+				pos = begin + len;
+				if (pos < offset) {
+					len = 0;
+					begin = pos;
+				}
+				if (pos > offset + length) {
+					read_unlock(&nl_table_lock);
+					goto done;
+				}
 			}
 		}
 		read_unlock(&nl_table_lock);
@@ -1015,14 +1229,60 @@ struct net_proto_family netlink_family_o
 	netlink_create
 };
 
-static int __init netlink_proto_init(void)
+extern void netlink_skb_parms_too_large(void);
+
+int __init netlink_proto_init(void)
 {
 	struct sk_buff *dummy_skb;
+	int i;
+	unsigned long max;
+	unsigned int order;
 
-	if (sizeof(struct netlink_skb_parms) > sizeof(dummy_skb->cb)) {
-		printk(KERN_CRIT "netlink_init: panic\n");
-		return -1;
+	if (sizeof(struct netlink_skb_parms) > sizeof(dummy_skb->cb))
+		netlink_skb_parms_too_large();
+
+	nl_table = kmalloc(sizeof(*nl_table) * MAX_LINKS, GFP_KERNEL);
+	if (!nl_table) {
+enomem:
+		printk(KERN_CRIT "netlink_init: Cannot allocate nl_table\n");
+		return -ENOMEM;
 	}
+
+	memset(nl_table, 0, sizeof(*nl_table) * MAX_LINKS);
+
+	if (num_physpages >= (128 * 1024))
+		max = num_physpages >> (21 - PAGE_SHIFT);
+	else
+		max = num_physpages >> (23 - PAGE_SHIFT);
+
+	for (order = 0; (1UL << order) < max + 1; order++)
+		;
+	order += PAGE_SHIFT - 1;
+	max = (1UL << order) / sizeof(struct sock *);
+	if (max > UINT_MAX)
+		max = UINT_MAX;
+	for (order = 0; (1UL << order) < max + 1; order++)
+		;
+	order--;
+
+	for (i = 0; i < MAX_LINKS; i++) {
+		struct nl_pid_hash *hash = &nl_table[i].hash;
+
+		hash->table = nl_pid_hash_alloc(1 * sizeof(*hash->table));
+		if (!hash->table) {
+			while (i-- > 0)
+				nl_pid_hash_free(nl_table[i].hash.table,
+						 1 * sizeof(*hash->table));
+			kfree(nl_table);
+			goto enomem;
+		}
+		memset(hash->table, 0, 1 * sizeof(*hash->table));
+		hash->max_shift = order;
+		hash->shift = 0;
+		hash->mask = 0;
+		hash->rehash_time = jiffies;
+	}
+
 	sock_register(&netlink_family_ops);
 #ifdef CONFIG_PROC_FS
 	create_proc_read_entry("net/netlink", 0, 0, netlink_read_proc, NULL);
@@ -1034,7 +1294,11 @@ static void __exit netlink_proto_exit(vo
 {
        sock_unregister(PF_NETLINK);
        remove_proc_entry("net/netlink", NULL);
+	kfree(nl_table);
+	nl_table = NULL;
 }
 
+#ifdef MODULE
 module_init(netlink_proto_init);
+#endif
 module_exit(netlink_proto_exit);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/net/netsyms.c linux-2.4.29-pre3/net/netsyms.c
--- linux-2.4.28/net/netsyms.c	2004-12-22 16:17:24.844185800 +0000
+++ linux-2.4.29-pre3/net/netsyms.c	2004-12-22 16:06:30.075725736 +0000
@@ -327,6 +327,7 @@ EXPORT_SYMBOL(tcp_hashinfo);
 EXPORT_SYMBOL(tcp_listen_wlock);
 EXPORT_SYMBOL(udp_hash);
 EXPORT_SYMBOL(udp_hash_lock);
+EXPORT_SYMBOL(udp_poll);
 
 EXPORT_SYMBOL(tcp_destroy_sock);
 EXPORT_SYMBOL(ip_queue_xmit);
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/net/sched/cls_tcindex.c linux-2.4.29-pre3/net/sched/cls_tcindex.c
--- linux-2.4.28/net/sched/cls_tcindex.c	2001-12-21 17:42:06.000000000 +0000
+++ linux-2.4.29-pre3/net/sched/cls_tcindex.c	2004-12-22 16:06:34.046122144 +0000
@@ -161,7 +161,8 @@ static int tcindex_init(struct tcf_proto
 }
 
 
-static int tcindex_delete(struct tcf_proto *tp, unsigned long arg)
+static int
+__tcindex_delete(struct tcf_proto *tp, unsigned long arg, int lock)
 {
 	struct tcindex_data *p = PRIV(tp);
 	struct tcindex_filter_result *r = (struct tcindex_filter_result *) arg;
@@ -184,9 +185,11 @@ static int tcindex_delete(struct tcf_pro
 
 found:
 		f = *walk;
-		tcf_tree_lock(tp); 
+		if (lock)
+			tcf_tree_lock(tp);
 		*walk = f->next;
-		tcf_tree_unlock(tp);
+		if (lock)
+			tcf_tree_unlock(tp);
 	}
 	cl = __cls_set_class(&r->res.class,0);
 	if (cl)
@@ -199,6 +202,10 @@ found:
 	return 0;
 }
 
+static int tcindex_delete(struct tcf_proto *tp, unsigned long arg)
+{
+	return __tcindex_delete(tp, arg, 1);
+}
 
 /*
  * There are no parameters for tcindex_init, so we overload tcindex_change
@@ -397,7 +404,7 @@ static void tcindex_walk(struct tcf_prot
 static int tcindex_destroy_element(struct tcf_proto *tp,
     unsigned long arg, struct tcf_walker *walker)
 {
-	return tcindex_delete(tp,arg);
+	return __tcindex_delete(tp, arg, 0);
 }
 
 
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/net/sched/sch_netem.c linux-2.4.29-pre3/net/sched/sch_netem.c
--- linux-2.4.28/net/sched/sch_netem.c	2004-12-22 16:17:25.003161632 +0000
+++ linux-2.4.29-pre3/net/sched/sch_netem.c	2004-12-22 16:06:42.051905080 +0000
@@ -259,12 +259,13 @@ static void netem_watchdog(unsigned long
 {
 	struct Qdisc *sch = (struct Qdisc *)arg;
 	struct netem_sched_data *q = qdisc_priv(sch);
+	struct net_device *dev = sch->dev;
 	struct sk_buff *skb;
 	psched_time_t now;
 
 	pr_debug("netem_watchdog: fired @%lu\n", jiffies);
 
-	spin_lock_bh(&sch->dev->queue_lock);
+	spin_lock_bh(&dev->queue_lock);
 	PSCHED_GET_TIME(now);
 
 	while ((skb = skb_peek(&q->delayed)) != NULL) {
@@ -284,8 +285,11 @@ static void netem_watchdog(unsigned long
 
 		if (q->qdisc->enqueue(skb, q->qdisc))
 			sch->stats.drops++;
+		else
+			sch->q.qlen++;
 	}
-	spin_unlock_bh(&sch->dev->queue_lock);
+	qdisc_run(dev);
+	spin_unlock_bh(&dev->queue_lock);
 }
 
 static void netem_reset(struct Qdisc *sch)
@@ -505,7 +509,7 @@ static int netem_graft(struct Qdisc *sch
 	sch_tree_lock(sch);
 	*old = xchg(&q->qdisc, new);
 	qdisc_reset(*old);
-	sch->q.qlen = q->delayed.qlen;
+	sch->q.qlen = 0;
 	sch_tree_unlock(sch);
 
 	return 0;
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/net/sctp/socket.c linux-2.4.29-pre3/net/sctp/socket.c
--- linux-2.4.28/net/sctp/socket.c	2004-12-22 16:17:25.651063136 +0000
+++ linux-2.4.29-pre3/net/sctp/socket.c	2004-12-22 16:05:54.000000000 +0000
@@ -4090,12 +4090,8 @@ SCTP_STATIC int sctp_msghdr_parse(const 
 	for (cmsg = CMSG_FIRSTHDR(msg);
 	     cmsg != NULL;
 	     cmsg = CMSG_NXTHDR((struct msghdr*)msg, cmsg)) {
-		/* Check for minimum length.  The SCM code has this check.  */
-		if (cmsg->cmsg_len < sizeof(struct cmsghdr) ||
-		    (unsigned long)(((char*)cmsg - (char*)msg->msg_control)
-				    + cmsg->cmsg_len) > msg->msg_controllen) {
+		if (!CMSG_OK(msg, cmsg))
 			return -EINVAL;
-		}
 
 		/* Should we parse this header or ignore?  */
 		if (cmsg->cmsg_level != IPPROTO_SCTP)
diff -Naur -p -X /home/marcelo/lib/dontdiff linux-2.4.28/net/socket.c linux-2.4.29-pre3/net/socket.c
--- linux-2.4.28/net/socket.c	2004-12-22 16:17:25.691057056 +0000
+++ linux-2.4.29-pre3/net/socket.c	2004-12-22 16:06:24.155625728 +0000
@@ -1716,6 +1716,7 @@ void __init sock_init(void)
 	 */
 
 #ifdef CONFIG_NET
+	netlink_proto_init();
 	rtnetlink_init();
 #endif
 #ifdef CONFIG_NETLINK_DEV
